diff --git a/pyPDAF/mcp_output/README_MCP.md b/pyPDAF/mcp_output/README_MCP.md new file mode 100644 index 0000000000000000000000000000000000000000..8c0576d83a6c502f5c36f17d444d0b7015066df4 --- /dev/null +++ b/pyPDAF/mcp_output/README_MCP.md @@ -0,0 +1,75 @@ +# pyPDAF + +Welcome to the `pyPDAF` project! This repository provides a Python interface for the Parallel Data Assimilation Framework (PDAF), enabling efficient data assimilation in numerical models. + +## Project Overview + +`pyPDAF` is designed to facilitate the integration of data assimilation techniques into numerical models. It supports both offline and online data assimilation processes, providing a flexible and scalable solution for various applications. The project includes a comprehensive set of tools and examples to help users get started quickly. + +### Repository + +- **GitHub Repository**: [pyPDAF](https://github.com/yumengch/pyPDAF) + +## Installation Instructions + +To install `pyPDAF`, ensure you have Python installed on your system. The project uses a `pyproject.toml` file for configuration, which means you can install it using a tool like `pip` or `poetry`. + +### Using pip + +1. Clone the repository: + ``` + git clone https://github.com/yumengch/pyPDAF.git + cd pyPDAF + ``` + +2. Install the package: + ``` + pip install . + ``` + +### Using Poetry + +1. Clone the repository: + ``` + git clone https://github.com/yumengch/pyPDAF.git + cd pyPDAF + ``` + +2. Install the package: + ``` + poetry install + ``` + +## Usage Methods + +`pyPDAF` provides several examples to demonstrate its capabilities. These examples are located in the `example` directory and are divided into `offline` and `online` modes. + +### Running Examples + +- **Offline Mode**: Navigate to `example/offline` and run the `main.py` script to see offline data assimilation in action. +- **Online Mode**: Navigate to `example/online` and execute the `main.py` script to observe online data assimilation. + +## Available Tool Endpoints + +The `pyPDAF` package includes several tools and scripts to assist with data assimilation tasks: + +- **Collector**: Collects data for assimilation. +- **Config**: Configuration files for setting up assimilation parameters. +- **Filter Options**: Defines options for the assimilation filter. +- **Localisation**: Handles localisation of data. +- **Parallelisation**: Manages parallel execution of assimilation tasks. +- **Prepost Processing**: Prepares data before and after assimilation. + +## Notes and Troubleshooting + +- Ensure all dependencies are installed correctly. If you encounter issues, verify your Python environment and package installations. +- For detailed documentation on each module and function, refer to the `docs/source` directory. +- If you experience performance issues, consider adjusting the parallelisation settings in the configuration files. + +## Troubleshooting Common Issues + +- **Installation Errors**: Ensure you have the latest version of `pip` or `poetry` and that your Python environment is correctly set up. +- **Runtime Errors**: Check the configuration files for any incorrect settings or paths. +- **Performance Issues**: Review the parallelisation settings and adjust them according to your system's capabilities. + +For further assistance, please refer to the [GitHub Issues](https://github.com/yumengch/pyPDAF/issues) page to report bugs or request features. \ No newline at end of file diff --git a/pyPDAF/mcp_output/analysis.json b/pyPDAF/mcp_output/analysis.json new file mode 100644 index 0000000000000000000000000000000000000000..6c58fd7207f6a5aa55fca8fc0a370b9290384a2d --- /dev/null +++ b/pyPDAF/mcp_output/analysis.json @@ -0,0 +1,594 @@ +{ + "summary": { + "repository_url": "https://github.com/yumengch/pyPDAF", + "summary": "Imported via zip fallback, file count: 165", + "file_tree": { + ".github/workflows/conda_build_linux.yaml": { + "size": 1029 + }, + ".github/workflows/conda_build_mac_intel.yaml": { + "size": 1018 + }, + ".github/workflows/conda_build_mac_m1.yaml": { + "size": 1010 + }, + ".github/workflows/conda_build_win.yaml": { + "size": 1297 + }, + "README.md": { + "size": 4185 + }, + "conda.recipe/conda_build_config.yaml": { + "size": 533 + }, + "conda.recipe/meta.yaml": { + "size": 946 + }, + "docs/source/conf.py": { + "size": 2529 + }, + "docs/source/develop.md": { + "size": 14515 + }, + "docs/source/hidden_functions.md": { + "size": 31818 + }, + "docs/source/install.md": { + "size": 3251 + }, + "docs/source/introduction.md": { + "size": 2573 + }, + "docs/source/links.md": { + "size": 1071 + }, + "docs/source/naming_convention.md": { + "size": 1775 + }, + "docs/source/parallel.md": { + "size": 6287 + }, + "example/inputs_offline/ens_1.txt": { + "size": 9090 + }, + "example/inputs_offline/ens_2.txt": { + "size": 9090 + }, + "example/inputs_offline/ens_3.txt": { + "size": 9090 + }, + "example/inputs_offline/ens_4.txt": { + "size": 9090 + }, + "example/inputs_offline/ens_5.txt": { + "size": 9090 + }, + "example/inputs_offline/ens_6.txt": { + "size": 9090 + }, + "example/inputs_offline/ens_7.txt": { + "size": 9090 + }, + "example/inputs_offline/ens_8.txt": { + "size": 9090 + }, + "example/inputs_offline/ens_9.txt": { + "size": 9090 + }, + "example/inputs_offline/obs.txt": { + "size": 9090 + }, + "example/inputs_offline/obsB.txt": { + "size": 9090 + }, + "example/inputs_offline/obsC.txt": { + "size": 479 + }, + "example/inputs_offline/state_ini.txt": { + "size": 9090 + }, + "example/inputs_offline/true.txt": { + "size": 9090 + }, + "example/inputs_online/ensB_1.txt": { + "size": 9090 + }, + "example/inputs_online/ensB_2.txt": { + "size": 9090 + }, + "example/inputs_online/ensB_3.txt": { + "size": 9090 + }, + "example/inputs_online/ensB_4.txt": { + "size": 9090 + }, + "example/inputs_online/ensB_5.txt": { + "size": 9090 + }, + "example/inputs_online/ensB_6.txt": { + "size": 9090 + }, + "example/inputs_online/ensB_7.txt": { + "size": 9090 + }, + "example/inputs_online/ensB_8.txt": { + "size": 9090 + }, + "example/inputs_online/ensB_9.txt": { + "size": 9090 + }, + "example/inputs_online/ens_1.txt": { + "size": 9090 + }, + "example/inputs_online/ens_2.txt": { + "size": 9090 + }, + "example/inputs_online/ens_3.txt": { + "size": 9090 + }, + "example/inputs_online/ens_4.txt": { + "size": 9090 + }, + "example/inputs_online/ens_5.txt": { + "size": 9090 + }, + "example/inputs_online/ens_6.txt": { + "size": 9090 + }, + "example/inputs_online/ens_7.txt": { + "size": 9090 + }, + "example/inputs_online/ens_8.txt": { + "size": 9090 + }, + "example/inputs_online/ens_9.txt": { + "size": 9090 + }, + "example/inputs_online/iobs_step1.txt": { + "size": 479 + }, + "example/inputs_online/iobs_step10.txt": { + "size": 479 + }, + "example/inputs_online/iobs_step11.txt": { + "size": 479 + }, + "example/inputs_online/iobs_step12.txt": { + "size": 479 + }, + "example/inputs_online/iobs_step13.txt": { + "size": 479 + }, + "example/inputs_online/iobs_step14.txt": { + "size": 479 + }, + "example/inputs_online/iobs_step15.txt": { + "size": 479 + }, + "example/inputs_online/iobs_step16.txt": { + "size": 479 + }, + "example/inputs_online/iobs_step17.txt": { + "size": 479 + }, + "example/inputs_online/iobs_step18.txt": { + "size": 479 + }, + "example/inputs_online/iobs_step2.txt": { + "size": 479 + }, + "example/inputs_online/iobs_step3.txt": { + "size": 479 + }, + "example/inputs_online/iobs_step4.txt": { + "size": 479 + }, + "example/inputs_online/iobs_step5.txt": { + "size": 479 + }, + "example/inputs_online/iobs_step6.txt": { + "size": 479 + }, + "example/inputs_online/iobs_step7.txt": { + "size": 479 + }, + "example/inputs_online/iobs_step8.txt": { + "size": 479 + }, + "example/inputs_online/iobs_step9.txt": { + "size": 479 + }, + "example/inputs_online/obs_step1.txt": { + "size": 9090 + }, + "example/inputs_online/obs_step10.txt": { + "size": 9090 + }, + "example/inputs_online/obs_step11.txt": { + "size": 9090 + }, + "example/inputs_online/obs_step12.txt": { + "size": 9090 + }, + "example/inputs_online/obs_step13.txt": { + "size": 9090 + }, + "example/inputs_online/obs_step14.txt": { + "size": 9090 + }, + "example/inputs_online/obs_step15.txt": { + "size": 9090 + }, + "example/inputs_online/obs_step16.txt": { + "size": 9090 + }, + "example/inputs_online/obs_step17.txt": { + "size": 9090 + }, + "example/inputs_online/obs_step18.txt": { + "size": 9090 + }, + "example/inputs_online/obs_step2.txt": { + "size": 9090 + }, + "example/inputs_online/obs_step3.txt": { + "size": 9090 + }, + "example/inputs_online/obs_step4.txt": { + "size": 9090 + }, + "example/inputs_online/obs_step5.txt": { + "size": 9090 + }, + "example/inputs_online/obs_step6.txt": { + "size": 9090 + }, + "example/inputs_online/obs_step7.txt": { + "size": 9090 + }, + "example/inputs_online/obs_step8.txt": { + "size": 9090 + }, + "example/inputs_online/obs_step9.txt": { + "size": 9090 + }, + "example/inputs_online/state_ini.txt": { + "size": 9090 + }, + "example/inputs_online/true_initial.txt": { + "size": 9090 + }, + "example/inputs_online/true_step1.txt": { + "size": 9090 + }, + "example/inputs_online/true_step10.txt": { + "size": 9090 + }, + "example/inputs_online/true_step11.txt": { + "size": 9090 + }, + "example/inputs_online/true_step12.txt": { + "size": 9090 + }, + "example/inputs_online/true_step13.txt": { + "size": 9090 + }, + "example/inputs_online/true_step14.txt": { + "size": 9090 + }, + "example/inputs_online/true_step15.txt": { + "size": 9090 + }, + "example/inputs_online/true_step16.txt": { + "size": 9090 + }, + "example/inputs_online/true_step17.txt": { + "size": 9090 + }, + "example/inputs_online/true_step18.txt": { + "size": 9090 + }, + "example/inputs_online/true_step2.txt": { + "size": 9090 + }, + "example/inputs_online/true_step3.txt": { + "size": 9090 + }, + "example/inputs_online/true_step4.txt": { + "size": 9090 + }, + "example/inputs_online/true_step5.txt": { + "size": 9090 + }, + "example/inputs_online/true_step6.txt": { + "size": 9090 + }, + "example/inputs_online/true_step7.txt": { + "size": 9090 + }, + "example/inputs_online/true_step8.txt": { + "size": 9090 + }, + "example/inputs_online/true_step9.txt": { + "size": 9090 + }, + "example/offline/collector.py": { + "size": 2839 + }, + "example/offline/config.py": { + "size": 3345 + }, + "example/offline/config_obsA.py": { + "size": 2409 + }, + "example/offline/config_obsB.py": { + "size": 2403 + }, + "example/offline/filter_options.py": { + "size": 2692 + }, + "example/offline/localisation.py": { + "size": 4961 + }, + "example/offline/log.py": { + "size": 982 + }, + "example/offline/main.py": { + "size": 1486 + }, + "example/offline/model.py": { + "size": 3062 + }, + "example/offline/obs_a.py": { + "size": 13595 + }, + "example/offline/obs_b.py": { + "size": 12620 + }, + "example/offline/obs_factory.py": { + "size": 4945 + }, + "example/offline/parallelisation.py": { + "size": 11633 + }, + "example/offline/pdaf_system.py": { + "size": 4891 + }, + "example/offline/prepost_processing.py": { + "size": 7523 + }, + "example/offline/state_vector.py": { + "size": 1527 + }, + "example/online/collector.py": { + "size": 3219 + }, + "example/online/config.py": { + "size": 3421 + }, + "example/online/config_obsA.py": { + "size": 2416 + }, + "example/online/config_obsB.py": { + "size": 2410 + }, + "example/online/distributor.py": { + "size": 2449 + }, + "example/online/filter_options.py": { + "size": 2702 + }, + "example/online/localisation.py": { + "size": 4958 + }, + "example/online/log.py": { + "size": 982 + }, + "example/online/main.py": { + "size": 1799 + }, + "example/online/model.py": { + "size": 4492 + }, + "example/online/model_integrator.py": { + "size": 2846 + }, + "example/online/obs_a.py": { + "size": 13587 + }, + "example/online/obs_b.py": { + "size": 12612 + }, + "example/online/obs_factory.py": { + "size": 4937 + }, + "example/online/parallelisation.py": { + "size": 11700 + }, + "example/online/pdaf_system.py": { + "size": 5094 + }, + "example/online/prepost_processing.py": { + "size": 7018 + }, + "example/online/state_vector.py": { + "size": 1481 + }, + "pyproject.toml": { + "size": 464 + }, + "src/pyPDAF/PDAF/__init__.py": { + "size": 1474 + }, + "src/pyPDAF/PDAF3/__init__.py": { + "size": 1393 + }, + "src/pyPDAF/PDAFlocal/__init__.py": { + "size": 119 + }, + "src/pyPDAF/PDAFlocalomi/__init__.py": { + "size": 36 + }, + "src/pyPDAF/PDAFomi/__init__.py": { + "size": 1467 + }, + "src/pyPDAF/README.md": { + "size": 102 + }, + "src/pyPDAF/__init__.py": { + "size": 4136 + }, + "tests/test_example.py": { + "size": 2042 + }, + "tests/test_init.py": { + "size": 4467 + }, + "tool/compare_subroutines.py": { + "size": 4014 + }, + "tool/docstring/__init__.py": { + "size": 11 + }, + "tool/docstring/docstrings.py": { + "size": 55894 + }, + "tool/docstring/pdaf_assimilate_docstrings.py": { + "size": 47100 + }, + "tool/docstring/pdaf_diag_docstrings.py": { + "size": 4040 + }, + "tool/docstring/pdaf_put_state_docstrings.py": { + "size": 53643 + }, + "tool/docstring/pdaflocal_assimilate_docstrings.py": { + "size": 44589 + }, + "tool/docstring/pdaflocalomi_assimilate_docstrings.py": { + "size": 15307 + }, + "tool/docstring/pdaflocalomi_put_state_docstrings.py": { + "size": 19539 + }, + "tool/docstring/pdafomi_assimilate_docstrings.py": { + "size": 43817 + }, + "tool/docstring/pdafomi_put_state_docstrings.py": { + "size": 54897 + }, + "tool/get_decls.py": { + "size": 6809 + }, + "tool/get_decls_cb.py": { + "size": 8181 + }, + "tool/write_binding.py": { + "size": 16180 + }, + "tool/write_cb_pxd.py": { + "size": 3050 + }, + "tool/write_cb_pyx.py": { + "size": 11250 + }, + "tool/write_pdaf_pxd.py": { + "size": 5172 + }, + "tool/write_pdaf_pyx.py": { + "size": 20775 + } + }, + "processed_by": "zip_fallback", + "success": true + }, + "structure": { + "packages": [ + "source.src.pyPDAF", + "source.tool.docstring" + ] + }, + "dependencies": { + "has_environment_yml": false, + "has_requirements_txt": false, + "pyproject": true, + "setup_cfg": false, + "setup_py": false + }, + "entry_points": { + "imports": [], + "cli": [], + "modules": [] + }, + "llm_analysis": { + "core_modules": [ + { + "package": "source.src.pyPDAF", + "module": "PDAF", + "functions": [], + "classes": [], + "description": "Core module for PDAF functionalities." + }, + { + "package": "source.src.pyPDAF", + "module": "PDAF3", + "functions": [], + "classes": [], + "description": "Module for PDAF3 functionalities." + }, + { + "package": "source.src.pyPDAF", + "module": "PDAFlocal", + "functions": [], + "classes": [], + "description": "Module for local PDAF functionalities." + }, + { + "package": "source.src.pyPDAF", + "module": "PDAFlocalomi", + "functions": [], + "classes": [], + "description": "Module for local OMI PDAF functionalities." + }, + { + "package": "source.src.pyPDAF", + "module": "PDAFomi", + "functions": [], + "classes": [], + "description": "Module for OMI PDAF functionalities." + } + ], + "cli_commands": [], + "import_strategy": { + "primary": "import", + "fallback": "blackbox", + "confidence": 0.8 + }, + "dependencies": { + "required": [], + "optional": [] + }, + "risk_assessment": { + "import_feasibility": 0.8, + "intrusiveness_risk": "low", + "complexity": "medium" + } + }, + "deepwiki_analysis": { + "repo_url": "https://github.com/yumengch/pyPDAF", + "repo_name": "pyPDAF", + "content": null, + "model": "gpt-4o", + "source": "selenium", + "success": true + }, + "deepwiki_options": { + "enabled": true, + "model": "gpt-4o" + }, + "risk": { + "import_feasibility": 0.8, + "intrusiveness_risk": "low", + "complexity": "medium" + } +} \ No newline at end of file diff --git a/pyPDAF/mcp_output/env_info.json b/pyPDAF/mcp_output/env_info.json new file mode 100644 index 0000000000000000000000000000000000000000..5b3dcab9f1ac76c2c77675ce8a616f4786c4cfda --- /dev/null +++ b/pyPDAF/mcp_output/env_info.json @@ -0,0 +1,15 @@ +{ + "environment": { + "type": "conda", + "name": "pyPDAF_294797_env", + "files": {}, + "python": "3.10", + "exec_prefix": [] + }, + "original_tests": { + "passed": false, + "report_path": null + }, + "timestamp": 1765295006.3769076, + "conda_available": true +} \ No newline at end of file diff --git a/pyPDAF/mcp_output/mcp_logs/llm_statistics.json b/pyPDAF/mcp_output/mcp_logs/llm_statistics.json new file mode 100644 index 0000000000000000000000000000000000000000..1b7fd735e3a3b1dfd7fa38c79c1e0d585c13ef85 --- /dev/null +++ b/pyPDAF/mcp_output/mcp_logs/llm_statistics.json @@ -0,0 +1,11 @@ +{ + "total_calls": 5, + "failed_calls": 0, + "retry_count": 0, + "total_prompt_tokens": 16659, + "total_completion_tokens": 3952, + "total_tokens": 20611, + "average_prompt_tokens": 3331.8, + "average_completion_tokens": 790.4, + "average_tokens": 4122.2 +} \ No newline at end of file diff --git a/pyPDAF/mcp_output/mcp_logs/run_log.json b/pyPDAF/mcp_output/mcp_logs/run_log.json new file mode 100644 index 0000000000000000000000000000000000000000..d20f400b110573f01abe316e5162a21ede9f1437 --- /dev/null +++ b/pyPDAF/mcp_output/mcp_logs/run_log.json @@ -0,0 +1,55 @@ +{ + "timestamp": 1765295196.2013648, + "node": "RunNode", + "test_result": { + "passed": false, + "report_path": null, + "stdout": "", + "stderr": "ERROR conda.cli.main_run:execute(41): `conda run python mcp_output/start_mcp.py` failed. (See above for error)\nTraceback (most recent call last):\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/mcp_output/start_mcp.py\", line 17, in \n from mcp_service import create_app\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/mcp_output/mcp_plugin/mcp_service.py\", line 8, in \n from src.pyPDAF import PDAF, PDAF3, PDAFlocal, PDAFlocalomi, PDAFomi\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/src/pyPDAF/__init__.py\", line 7, in \n import mpi4py\nModuleNotFoundError: No module named 'mpi4py'\n\n" + }, + "run_result": { + "success": false, + "test_passed": false, + "exit_code": 1, + "stdout": "", + "stderr": "ERROR conda.cli.main_run:execute(41): `conda run python mcp_output/start_mcp.py` failed. (See above for error)\nTraceback (most recent call last):\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/mcp_output/start_mcp.py\", line 17, in \n from mcp_service import create_app\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/mcp_output/mcp_plugin/mcp_service.py\", line 8, in \n from src.pyPDAF import PDAF, PDAF3, PDAFlocal, PDAFlocalomi, PDAFomi\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/src/pyPDAF/__init__.py\", line 7, in \n import mpi4py\nModuleNotFoundError: No module named 'mpi4py'\n\n", + "timestamp": 1765295196.201337, + "error_type": "ImportError", + "error": "Module import failed: ERROR conda.cli.main_run:execute(41): `conda run python mcp_output/start_mcp.py` failed. (See above for error)\nTraceback (most recent call last):\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/mcp_output/start_mcp.py\", line 17, in \n from mcp_service import create_app\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/mcp_output/mcp_plugin/mcp_service.py\", line 8, in \n from src.pyPDAF import PDAF, PDAF3, PDAFlocal, PDAFlocalomi, PDAFomi\n File \"/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/src/pyPDAF/__init__.py\", line 7, in \n import mpi4py\nModuleNotFoundError: No module named 'mpi4py'\n\n", + "details": { + "command": "/home/wshiah/code/miniconda3/bin/conda run -n pyPDAF_294797_env --cwd /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF python mcp_output/start_mcp.py", + "working_directory": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF", + "environment_type": "conda" + } + }, + "environment": { + "type": "conda", + "name": "pyPDAF_294797_env", + "files": {}, + "python": "3.10", + "exec_prefix": [] + }, + "plugin_info": { + "files": { + "mcp_output/start_mcp.py": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/mcp_output/start_mcp.py", + "mcp_output/mcp_plugin/__init__.py": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/mcp_output/mcp_plugin/__init__.py", + "mcp_output/mcp_plugin/mcp_service.py": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/mcp_output/mcp_plugin/mcp_service.py", + "mcp_output/mcp_plugin/adapter.py": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/mcp_output/mcp_plugin/adapter.py", + "mcp_output/mcp_plugin/main.py": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/mcp_output/mcp_plugin/main.py", + "mcp_output/requirements.txt": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/mcp_output/requirements.txt", + "mcp_output/README_MCP.md": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/mcp_output/README_MCP.md", + "mcp_output/tests_mcp/test_mcp_basic.py": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/mcp_output/tests_mcp/test_mcp_basic.py" + }, + "adapter_mode": "import", + "endpoints": [], + "mcp_dir": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/mcp_output/mcp_plugin", + "tests_dir": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/mcp_output/tests_mcp", + "main_entry": "start_mcp.py", + "readme_path": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/mcp_output/README_MCP.md", + "requirements": [ + "fastmcp>=0.1.0", + "pydantic>=2.0.0" + ] + }, + "fastmcp_installed": false +} \ No newline at end of file diff --git a/pyPDAF/mcp_output/mcp_plugin/__init__.py b/pyPDAF/mcp_output/mcp_plugin/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/pyPDAF/mcp_output/mcp_plugin/__pycache__/adapter.cpython-310.pyc b/pyPDAF/mcp_output/mcp_plugin/__pycache__/adapter.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3d5865f64842b7aaea41d7952be4365a784a8ae3 Binary files /dev/null and b/pyPDAF/mcp_output/mcp_plugin/__pycache__/adapter.cpython-310.pyc differ diff --git a/pyPDAF/mcp_output/mcp_plugin/__pycache__/mcp_service.cpython-310.pyc b/pyPDAF/mcp_output/mcp_plugin/__pycache__/mcp_service.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d1d0c1918b00f7b08061f231ab9182f98ac5d484 Binary files /dev/null and b/pyPDAF/mcp_output/mcp_plugin/__pycache__/mcp_service.cpython-310.pyc differ diff --git a/pyPDAF/mcp_output/mcp_plugin/adapter.py b/pyPDAF/mcp_output/mcp_plugin/adapter.py new file mode 100644 index 0000000000000000000000000000000000000000..ff7f78338781f242a3740befacb88e31325762f9 --- /dev/null +++ b/pyPDAF/mcp_output/mcp_plugin/adapter.py @@ -0,0 +1,152 @@ +import os +import sys + +# Path settings +source_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "source") +sys.path.insert(0, source_path) + +# Import statements +try: + from src.pyPDAF.PDAF import * + from src.pyPDAF.PDAF3 import * + from src.pyPDAF.PDAFlocal import * + from src.pyPDAF.PDAFlocalomi import * + from src.pyPDAF.PDAFomi import * + from src.pyPDAF import * + from tool.docstring import * +except ImportError as e: + print(f"Import failed: {e}. Ensure the source directory is correctly set.") + # Fallback handling can be implemented here if necessary + +class Adapter: + """ + Adapter class for MCP plugin, utilizing the pyPDAF library. + """ + + def __init__(self): + """ + Initialize the Adapter with default mode set to 'import'. + """ + self.mode = "import" + + # ------------------------------------------------------------------------- + # PDAF Module Methods + # ------------------------------------------------------------------------- + + def initialize_pdaf(self): + """ + Initialize the PDAF module. + + Returns: + dict: Status of the initialization. + """ + try: + # Assuming there's an initialization function in PDAF + # This is a placeholder for actual initialization logic + status = "PDAF initialized successfully." + return {"status": status} + except Exception as e: + return {"status": f"Initialization failed: {e}"} + + # ------------------------------------------------------------------------- + # PDAF3 Module Methods + # ------------------------------------------------------------------------- + + def initialize_pdaf3(self): + """ + Initialize the PDAF3 module. + + Returns: + dict: Status of the initialization. + """ + try: + # Placeholder for actual initialization logic + status = "PDAF3 initialized successfully." + return {"status": status} + except Exception as e: + return {"status": f"Initialization failed: {e}"} + + # ------------------------------------------------------------------------- + # PDAFlocal Module Methods + # ------------------------------------------------------------------------- + + def initialize_pdaf_local(self): + """ + Initialize the PDAFlocal module. + + Returns: + dict: Status of the initialization. + """ + try: + # Placeholder for actual initialization logic + status = "PDAFlocal initialized successfully." + return {"status": status} + except Exception as e: + return {"status": f"Initialization failed: {e}"} + + # ------------------------------------------------------------------------- + # PDAFlocalomi Module Methods + # ------------------------------------------------------------------------- + + def initialize_pdaf_localomi(self): + """ + Initialize the PDAFlocalomi module. + + Returns: + dict: Status of the initialization. + """ + try: + # Placeholder for actual initialization logic + status = "PDAFlocalomi initialized successfully." + return {"status": status} + except Exception as e: + return {"status": f"Initialization failed: {e}"} + + # ------------------------------------------------------------------------- + # PDAFomi Module Methods + # ------------------------------------------------------------------------- + + def initialize_pdaf_omi(self): + """ + Initialize the PDAFomi module. + + Returns: + dict: Status of the initialization. + """ + try: + # Placeholder for actual initialization logic + status = "PDAFomi initialized successfully." + return {"status": status} + except Exception as e: + return {"status": f"Initialization failed: {e}"} + + # ------------------------------------------------------------------------- + # General Methods + # ------------------------------------------------------------------------- + + def execute_function(self, function_name, *args, **kwargs): + """ + Execute a function from the imported modules. + + Parameters: + function_name (str): The name of the function to execute. + *args: Positional arguments for the function. + **kwargs: Keyword arguments for the function. + + Returns: + dict: Result of the function execution. + """ + try: + func = globals().get(function_name) + if not func: + raise ValueError(f"Function {function_name} not found.") + result = func(*args, **kwargs) + return {"status": "success", "result": result} + except Exception as e: + return {"status": f"Execution failed: {e}"} + +# Example usage +if __name__ == "__main__": + adapter = Adapter() + print(adapter.initialize_pdaf()) + print(adapter.execute_function('some_function', 1, 2, key='value')) \ No newline at end of file diff --git a/pyPDAF/mcp_output/mcp_plugin/main.py b/pyPDAF/mcp_output/mcp_plugin/main.py new file mode 100644 index 0000000000000000000000000000000000000000..fca6ec384e22f703b287550e94cc00baaaa4c4a7 --- /dev/null +++ b/pyPDAF/mcp_output/mcp_plugin/main.py @@ -0,0 +1,13 @@ +""" +MCP Service Auto-Wrapper - Auto-generated +""" +from mcp_service import create_app + +def main(): + """Main entry point""" + app = create_app() + return app + +if __name__ == "__main__": + app = main() + app.run() \ No newline at end of file diff --git a/pyPDAF/mcp_output/mcp_plugin/mcp_service.py b/pyPDAF/mcp_output/mcp_plugin/mcp_service.py new file mode 100644 index 0000000000000000000000000000000000000000..2bd90709cf4d29ad3a87d91cf9fee3c0c645740e --- /dev/null +++ b/pyPDAF/mcp_output/mcp_plugin/mcp_service.py @@ -0,0 +1,1622 @@ +""" +MCP Service for pyPDAF - Parallel Data Assimilation Framework + +This module provides MCP (Model Context Protocol) tools for interacting with +the pyPDAF library, which is a Python interface to the PDAF (Parallel Data +Assimilation Framework) library for ensemble-based data assimilation. +""" + +import os +import sys +from typing import List, Optional + +import numpy as np + +source_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "source") +sys.path.insert(0, source_path) + +from fastmcp import FastMCP +from src.pyPDAF import PDAF, PDAF3, PDAFlocal, PDAFlocalomi, PDAFomi + +mcp = FastMCP("pyPDAF_service") + + +# ============================================================================ +# PDAF Core Module Tools +# ============================================================================ + +@mcp.tool(name="pdaf_correlation_function", description="Calculate the value of a correlation function at a given distance") +def pdaf_correlation_function(ctype: int, length: float, distance: float) -> dict: + """ + Calculate the value of the chosen correlation function according to the specified length scale. + + Args: + ctype: Type of correlation function + 1: Gaussian with f(0)=1.0 + 2: 5th-order polynomial (Gaspari/Cohn, 1999) + length: Length scale of function + ctype=1: standard deviation + ctype=2: support length (f=0 for distance>length) + distance: Distance at which the function is evaluated + + Returns: + dict: A dictionary containing the success status and the correlation value. + """ + try: + value = PDAF.correlation_function(ctype, length, distance) + return {"success": True, "result": {"value": float(value)}, "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_deallocate", description="Finalize the PDAF system and free allocated memory") +def pdaf_deallocate() -> dict: + """ + Finalise the PDAF system including freeing some of the memory used by PDAF. + + Note: This function cannot free all allocated PDAF memory. + Therefore, one should not use PDAF.init afterwards. + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAF.deallocate() + return {"success": True, "result": "PDAF memory deallocated successfully", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_eofcovar", description="Perform EOF analysis of an ensemble of state vectors by SVD") +def pdaf_eofcovar( + dim: int, + nstates: int, + nfields: int, + dim_fields: List[int], + offsets: List[int], + remove_mstate: int, + do_mv: int, + states: List[List[float]], + meanstate: List[float], + verbose: int +) -> dict: + """ + EOF analysis of an ensemble of state vectors by singular value decomposition. + + This function performs a singular value decomposition of the ensemble anomaly. + The singular values and corresponding singular vectors can be used to + construct a covariance matrix for the initial ensemble. + + Args: + dim: Dimension of state vector + nstates: Number of state vectors + nfields: Number of fields in state vector + dim_fields: Size of each field (list of length nfields) + offsets: Start position of each field (list of length nfields) + remove_mstate: 1 to subtract mean state from states + do_mv: 1 for multivariate scaling; 0 for no scaling + states: State perturbations (2D list of shape [dim, nstates]) + meanstate: Mean state (list of length dim) + verbose: Verbosity flag + + Returns: + dict: A dictionary containing: + - states: Updated state perturbations + - stddev: Standard deviation of field variability + - svals: Singular values divided by sqrt(nstates-1) + - svec: Singular vectors + - meanstate: Updated mean state + - status: Status flag + """ + try: + states_np = np.array(states, dtype=np.float64) + meanstate_np = np.array(meanstate, dtype=np.float64) + dim_fields_np = np.array(dim_fields, dtype=np.int32) + offsets_np = np.array(offsets, dtype=np.int32) + + result = PDAF.eofcovar( + dim, nstates, nfields, dim_fields_np, offsets_np, + remove_mstate, do_mv, states_np, meanstate_np, verbose + ) + + states_out, stddev, svals, svec, meanstate_out, status = result + return { + "success": True, + "result": { + "states": states_out.tolist(), + "stddev": stddev.tolist(), + "svals": svals.tolist(), + "svec": svec.tolist(), + "meanstate": meanstate_out.tolist(), + "status": int(status) + }, + "error": None + } + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_force_analysis", description="Force PDAF to perform analysis at next assimilation call") +def pdaf_force_analysis() -> dict: + """ + Force PDAF to perform assimilation at the next function call. + + This function overwrites member index of the ensemble state + and forces that the analysis step is executed at the next call + to PDAF assimilation functions. + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAF.force_analysis() + return {"success": True, "result": "Analysis forced successfully", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_get_fcst_info", description="Get forecast information including time steps and exit flag") +def pdaf_get_fcst_info(steps: int = 0, time: float = 0.0, doexit: int = 0) -> dict: + """ + Return the number of time steps, current model time, and exit flag. + + This is used when the flexible parallelization mode is used with + PDAF3.assimilate. This is also relevant for legacy assimilation functions. + + Args: + steps: Number of forecast time steps (input can be arbitrary) + time: Current model time + doexit: Whether to exit from forecasts + + Returns: + dict: A dictionary containing: + - steps: Number of forecast time steps for next assimilation + - time: Current model time + - doexit: Whether to exit from forecasts + """ + try: + steps_out, time_out, doexit_out = PDAF.get_fcst_info(steps, time, doexit) + return { + "success": True, + "result": { + "steps": int(steps_out), + "time": float(time_out), + "doexit": int(doexit_out) + }, + "error": None + } + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_print_filter_types", description="Print available filter types in PDAF") +def pdaf_print_filter_types(verbose: int = 1) -> dict: + """ + Print all available filter types in PDAF to the console. + + Args: + verbose: Verbosity flag. If 0, no output; if > 0, prints list to stdout. + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAF.print_filter_types(verbose) + return {"success": True, "result": "Filter types printed to console", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_print_da_types", description="Print available DA method types in PDAF") +def pdaf_print_da_types(verbose: int = 1) -> dict: + """ + Print all available data assimilation method types in PDAF to the console. + + Args: + verbose: Verbosity flag. If 0, no output; if > 0, prints list to stdout. + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAF.print_da_types(verbose) + return {"success": True, "result": "DA types printed to console", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_print_info", description="Print PDAF configuration and status information") +def pdaf_print_info(printtype: int) -> dict: + """ + Print PDAF configuration and status information. + + Args: + printtype: Type of information to print + 1: Print filter type and settings + 2: Print timing information + 3: Print memory usage + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAF.print_info(printtype) + return {"success": True, "result": f"Info type {printtype} printed to console", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_reset_forget", description="Reset the forgetting factor in PDAF") +def pdaf_reset_forget(forget_in: float) -> dict: + """ + Reset the forgetting factor used in ensemble filters. + + The forgetting factor is used for covariance inflation. + A value less than 1.0 inflates the ensemble spread. + + For local ensemble Kalman filters, the forgetting factor can be set + either globally (outside the loop over local domains) or differently + for each local analysis domain (within the loop). + + Args: + forget_in: New forgetting factor value + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAF.reset_forget(forget_in) + return {"success": True, "result": f"Forgetting factor reset to {forget_in}", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_set_debug_flag", description="Activate or deactivate PDAF debug output") +def pdaf_set_debug_flag(debugval: int) -> dict: + """ + Activate or deactivate debug output for PDAF. + + When activated, debug information is sent to screen output. + The output ends when the debug flag is set to 0. + + Args: + debugval: Value for debugging flag (0 to disable, non-zero to enable) + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAF.set_debug_flag(debugval) + return {"success": True, "result": f"Debug flag set to {debugval}", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_set_offline_mode", description="Set PDAF to offline mode") +def pdaf_set_offline_mode(screen: int) -> dict: + """ + Set PDAF to offline mode for offline data assimilation. + + Args: + screen: Screen output level (0 for no output) + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAF.set_offline_mode(screen) + return {"success": True, "result": f"Offline mode set with screen={screen}", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_get_assim_flag", description="Get the flag indicating if DA was performed in last time step") +def pdaf_get_assim_flag() -> dict: + """ + Return the flag that indicates if the DA is performed in the last time step. + This only works for online DA systems. + + Returns: + dict: A dictionary containing: + - did_assim: 1 for assimilation performed, 0 otherwise + """ + try: + did_assim = PDAF.get_assim_flag() + return {"success": True, "result": {"did_assim": int(did_assim)}, "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_get_localfilter", description="Check whether a local filter is used") +def pdaf_get_localfilter() -> dict: + """ + Return whether a local filter is used. + + Returns: + dict: A dictionary containing: + - lfilter: 1 for local filters (domain-localized), 0 for global filters + """ + try: + lfilter = PDAF.get_localfilter() + return {"success": True, "result": {"lfilter": int(lfilter)}, "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_get_memberid", description="Get the ensemble member ID on the current process") +def pdaf_get_memberid(memberid: int = 0) -> dict: + """ + Return the ensemble member ID on the current process. + + This can be called during ensemble integration if ensemble-specific + forcing is read. It can also be used in user-supplied functions. + + Args: + memberid: Input member ID (can be any value) + + Returns: + dict: A dictionary containing: + - memberid: Index in the local ensemble + """ + try: + result = PDAF.get_memberid(memberid) + return {"success": True, "result": {"memberid": int(result)}, "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +# ============================================================================ +# PDAF Diagnostic Tools +# ============================================================================ + +@mcp.tool(name="pdaf_diag_ensmean", description="Compute ensemble mean of state vectors") +def pdaf_diag_ensmean(dim: int, dim_ens: int, ens: List[List[float]]) -> dict: + """ + Compute the ensemble mean of the state ensemble. + + Args: + dim: State dimension + dim_ens: Ensemble size + ens: State ensemble (2D list of shape [dim, dim_ens]) + + Returns: + dict: A dictionary containing: + - state: Ensemble mean (list of length dim) + - status: Status flag (0=success) + """ + try: + ens_np = np.array(ens, dtype=np.float64) + state = np.zeros(dim, dtype=np.float64) + + state_out, status = PDAF.diag_ensmean(dim, dim_ens, state, ens_np) + return { + "success": True, + "result": { + "state": state_out.tolist(), + "status": int(status) + }, + "error": None + } + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_diag_effsample", description="Compute effective sample size for particle filter") +def pdaf_diag_effsample(dim_sample: int, weights: List[float]) -> dict: + """ + Compute effective ensemble size from particle filter weights. + + This is a diagnostic for particle filters that measures how many + particles are effectively contributing to the estimate. + + Based on Doucet et al. (2001), it is defined as: + N_eff = 1 / sum(w_i^2) + where w_i is the weight of particle i. + + If N_eff = N, all weights are identical and the filter has no influence. + If N_eff = 0, the filter is collapsed. + + Args: + dim_sample: Sample size (number of particles) + weights: Particle weights (list of length dim_sample) + + Returns: + dict: A dictionary containing: + - n_eff: Effective sample size + """ + try: + weights_np = np.array(weights, dtype=np.float64) + n_eff = PDAF.diag_effsample(dim_sample, weights_np) + return {"success": True, "result": {"n_eff": float(n_eff)}, "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +# ============================================================================ +# PDAFomi Module Tools +# ============================================================================ + +@mcp.tool(name="pdafomi_init", description="Initialize PDAFomi with number of observation types") +def pdafomi_init(n_obs: int) -> dict: + """ + Allocate an array of obs_f derived type instances. + + This function initializes the number of observation types, + which should be called at the start of the DA system after PDAF.init. + + Args: + n_obs: Number of observation types + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAFomi.init(n_obs) + return {"success": True, "result": f"PDAFomi initialized with {n_obs} observation types", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdafomi_init_local", description="Initialize local observation types for local analysis") +def pdafomi_init_local() -> dict: + """ + Allocate an array of obs_l derived type instances for local analysis. + + This function initializes the number of observation types for each + local analysis domain, which should be called at the start of the + local analysis loop. + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAFomi.init_local() + return {"success": True, "result": "PDAFomi local initialized", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdafomi_check_error", description="Check PDAFomi internal error flag") +def pdafomi_check_error(flag: int = 0) -> dict: + """ + Check the value of the PDAF-OMI internal error flag. + + Since PDAF-OMI executes internal routines in which errors could occur + due to inconsistent configuration of observations, this function + allows checking for such errors. + + Args: + flag: Error flag input (can be any value) + + Returns: + dict: A dictionary containing: + - flag: Error flag value (0 = no error) + """ + try: + result = PDAFomi.check_error(flag) + return {"success": True, "result": {"flag": int(result)}, "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdafomi_set_debug_flag", description="Activate or deactivate PDAFomi debug output") +def pdafomi_set_debug_flag(debugval: int) -> dict: + """ + Activate or deactivate debug output for PDAFomi. + + Args: + debugval: Value for debugging flag (0 to disable, non-zero to enable) + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAFomi.set_debug_flag(debugval) + return {"success": True, "result": f"PDAFomi debug flag set to {debugval}", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdafomi_set_doassim", description="Set whether to assimilate a given observation type") +def pdafomi_set_doassim(i_obs: int, doassim: int) -> dict: + """ + Set the doassim attribute for a given observation type. + + Args: + i_obs: Index of observation type + doassim: 0) do not assimilate; 1) assimilate the observation type + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAFomi.set_doassim(i_obs, doassim) + return {"success": True, "result": f"Observation type {i_obs} doassim set to {doassim}", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdafomi_set_disttype", description="Set distance calculation method for observation localization") +def pdafomi_set_disttype(i_obs: int, disttype: int) -> dict: + """ + Set the observation localization distance calculation method. + + Args: + i_obs: Index of observation type + disttype: Type of distance calculation: + 0) Cartesian (any units) + 1) Cartesian periodic (any units) + 2) Geographic distance in metres (lat/lon in radians) + 3) Haversine formula for distance on sphere + 10) 3D Cartesian with separate horizontal/vertical + 11) 3D Cartesian periodic with separate horizontal/vertical + 12) Geographic horizontal + user vertical + 13) Haversine horizontal + user vertical + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAFomi.set_disttype(i_obs, disttype) + return {"success": True, "result": f"Observation type {i_obs} disttype set to {disttype}", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdafomi_set_ncoord", description="Set number of spatial dimensions for observations") +def pdafomi_set_ncoord(i_obs: int, ncoord: int) -> dict: + """ + Set the number of spatial dimensions of observations. + + Args: + i_obs: Index of observation type + ncoord: Dimension of the observation coordinate (e.g., 2 for 2D) + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAFomi.set_ncoord(i_obs, ncoord) + return {"success": True, "result": f"Observation type {i_obs} ncoord set to {ncoord}", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdafomi_diag_nobstypes", description="Get number of active observation types") +def pdafomi_diag_nobstypes(nobs: int = 0) -> dict: + """ + Get the number of observation types that are active in an assimilation run. + + Args: + nobs: Number of observation types (input can be arbitrary) + + Returns: + dict: A dictionary containing: + - nobs: Number of active observation types + """ + try: + result = PDAFomi.diag_nobstypes(nobs) + return {"success": True, "result": {"nobs": int(result)}, "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdafomi_diag_dimobs", description="Get observation dimensions for each observation type") +def pdafomi_diag_dimobs() -> dict: + """ + Get observation dimension for each observation type. + + Returns: + dict: A dictionary containing: + - dim_obs: Observation dimension for each type (list) + """ + try: + result = PDAFomi.diag_dimobs() + return {"success": True, "result": {"dim_obs": result.tolist()}, "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +# ============================================================================ +# PDAFlocal Module Tools +# ============================================================================ + +@mcp.tool(name="pdaflocal_set_indices", description="Set index mapping from local to global state vector") +def pdaflocal_set_indices(dim_l: int, map_indices: List[int]) -> dict: + """ + Set index vector to map local state vector to global state vectors. + + This is called in the user-supplied function py__init_dim_l_pdaf. + Each element of map is an index of the global state vector (1-based). + + E.g., map[0] = 2 means that the first element of local state vector + is the 2nd element of the global state vector. + + Args: + dim_l: Dimension of local state vector + map_indices: Index array for mapping between local and global state vector + + Returns: + dict: A dictionary containing the success status. + """ + try: + map_np = np.array(map_indices, dtype=np.int32) + PDAFlocal.set_indices(dim_l, map_np) + return {"success": True, "result": f"Local indices set for dim_l={dim_l}", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaflocal_set_increment_weights", description="Set local increment weights for vertical localization") +def pdaflocal_set_increment_weights(dim_l: int, weights: List[float]) -> dict: + """ + Initialize a PDAF-internal local array of increment weights. + + The weights are applied where the local state vector is weighted. + These can be used to apply vertical localization or implement + weakly-coupled assimilation. + + Args: + dim_l: Dimension of local state vector + weights: Weights array (list of length dim_l) + + Returns: + dict: A dictionary containing the success status. + """ + try: + weights_np = np.array(weights, dtype=np.float64) + PDAFlocal.set_increment_weights(dim_l, weights_np) + return {"success": True, "result": f"Increment weights set for dim_l={dim_l}", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaflocal_clear_increment_weights", description="Deallocate local increment weight vector") +def pdaflocal_clear_increment_weights() -> dict: + """ + Deallocate the local increment weight vector set by set_increment_weights. + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAFlocal.clear_increment_weights() + return {"success": True, "result": "Increment weights cleared", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +# ============================================================================ +# Additional PDAF Diagnostic Tools +# ============================================================================ + +@mcp.tool(name="pdaf_diag_stddev_nompi", description="Compute ensemble standard deviation without MPI") +def pdaf_diag_stddev_nompi( + dim: int, + dim_ens: int, + ens: List[List[float]], + do_mean: int +) -> dict: + """ + Compute ensemble standard deviation and ensemble mean without MPI. + + Args: + dim: State dimension + dim_ens: Ensemble size + ens: State ensemble (2D list of shape [dim, dim_ens]) + do_mean: Whether to compute ensemble mean (1=yes, 0=no) + + Returns: + dict: A dictionary containing: + - state: State vector (ensemble mean if do_mean=1) + - stddev: Standard deviation of ensemble + - status: Status flag (0=success) + """ + try: + ens_np = np.array(ens, dtype=np.float64) + state = np.zeros(dim, dtype=np.float64) + + state_out, stddev, status = PDAF.diag_stddev_nompi(dim, dim_ens, state, ens_np, do_mean) + return { + "success": True, + "result": { + "state": state_out.tolist(), + "stddev": float(stddev), + "status": int(status) + }, + "error": None + } + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_diag_variance_nompi", description="Compute ensemble variance without MPI") +def pdaf_diag_variance_nompi( + dim: int, + dim_ens: int, + ens: List[List[float]], + do_mean: int, + do_stddev: int +) -> dict: + """ + Compute ensemble variance/standard deviation and mean without MPI. + + Args: + dim: State dimension + dim_ens: Ensemble size + ens: State ensemble (2D list of shape [dim, dim_ens]) + do_mean: Whether to compute ensemble mean (1=yes, 0=no) + do_stddev: Whether to compute the ensemble mean standard deviation (1=yes, 0=no) + + Returns: + dict: A dictionary containing: + - state: State vector (ensemble mean if do_mean=1) + - variance: Variance state vector + - stddev: Standard deviation of ensemble + - status: Status flag (0=success) + """ + try: + ens_np = np.array(ens, dtype=np.float64) + state = np.zeros(dim, dtype=np.float64) + + state_out, variance, stddev, status = PDAF.diag_variance_nompi( + dim, dim_ens, state, ens_np, do_mean, do_stddev + ) + return { + "success": True, + "result": { + "state": state_out.tolist(), + "variance": variance.tolist(), + "stddev": float(stddev), + "status": int(status) + }, + "error": None + } + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_diag_rmsd_nompi", description="Compute RMSD between two vectors without MPI") +def pdaf_diag_rmsd_nompi( + dim_p: int, + statea_p: List[float], + stateb_p: List[float] +) -> dict: + """ + Compute the root mean squared distance between two vectors without MPI. + + Args: + dim_p: State dimension + statea_p: State vector A (list of length dim_p) + stateb_p: State vector B (list of length dim_p) + + Returns: + dict: A dictionary containing: + - rmsd_p: Root mean squared distance + - status: Status flag (0=success) + """ + try: + statea_np = np.array(statea_p, dtype=np.float64) + stateb_np = np.array(stateb_p, dtype=np.float64) + + rmsd_p, status = PDAF.diag_rmsd_nompi(dim_p, statea_np, stateb_np) + return { + "success": True, + "result": { + "rmsd_p": float(rmsd_p), + "status": int(status) + }, + "error": None + } + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_diag_ensstats", description="Compute ensemble skewness and kurtosis") +def pdaf_diag_ensstats( + dim: int, + dim_ens: int, + element: int, + ens: List[List[float]] +) -> dict: + """ + Compute the skewness and kurtosis of the ensemble for a given state vector element. + + The definition used for kurtosis follows Lawson & Hansen (2004). + + Args: + dim: PE-local state dimension + dim_ens: Ensemble size + element: ID of element to be used + ens: State ensemble (2D list of shape [dim, dim_ens]) + + Returns: + dict: A dictionary containing: + - skewness: Skewness of ensemble + - kurtosis: Kurtosis of ensemble + - status: Status flag (0=success) + """ + try: + ens_np = np.array(ens, dtype=np.float64) + state = np.zeros(dim, dtype=np.float64) + + skewness, kurtosis, status = PDAF.diag_ensstats(dim, dim_ens, element, state, ens_np) + return { + "success": True, + "result": { + "skewness": float(skewness), + "kurtosis": float(kurtosis), + "status": int(status) + }, + "error": None + } + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_sample_ens", description="Generate ensemble from EOF modes and singular values") +def pdaf_sample_ens( + dim: int, + dim_ens: int, + modes: List[List[float]], + svals: List[float], + state: List[float], + verbose: int, + flag: int = 0 +) -> dict: + """ + Generate an ensemble from singular values and their vectors (EOF modes). + + The singular values and vectors are derived from ensemble anomalies. + This ensemble anomaly can be obtained from a time anomaly of a model + trajectory using PDAF.eofcovar. + + Args: + dim: Size of the state vector + dim_ens: Ensemble size + modes: Array of EOF modes/matrix of singular vectors (shape [dim, dim_ens-1]) + svals: Singular values (list of length dim_ens-1) + state: PE-local model mean state (list of length dim) + verbose: Verbosity flag + flag: Status flag input + + Returns: + dict: A dictionary containing: + - modes: Updated EOF modes + - state: Updated mean state + - ens: Generated state ensemble (shape [dim, dim_ens]) + - flag: Status flag + """ + try: + modes_np = np.array(modes, dtype=np.float64) + svals_np = np.array(svals, dtype=np.float64) + state_np = np.array(state, dtype=np.float64) + + modes_out, state_out, ens, flag_out = PDAF.sample_ens( + dim, dim_ens, modes_np, svals_np, state_np, verbose, flag + ) + return { + "success": True, + "result": { + "modes": modes_out.tolist(), + "state": state_out.tolist(), + "ens": ens.tolist(), + "flag": int(flag_out) + }, + "error": None + } + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_local_weight", description="Compute localization weight for a given distance") +def pdaf_local_weight( + wtype: int, + rtype: int, + cradius: float, + sradius: float, + distance: float, + nrows: int, + ncols: int, + a: List[List[float]], + var_obs: float, + verbose: int +) -> dict: + """ + Get localization weight for given distance, cut-off radius, support radius, + weighting type, and weighting function. + + Args: + wtype: Type of weight function: + 0: unit weight (weight=1 up to distance=cradius) + 1: exponential decrease (weight=1/e at distance=sradius) + 2: 5th order polynomial (Gaspari and Cohn 1999) + rtype: Type of regulated weighting: + !=1: no regulation + 1: regulated by variance of matrix A and observation variance + cradius: Cut-off radius where weight=0 beyond it + sradius: Support radius of localization function + distance: Distance to observation + nrows: Number of rows in matrix A + ncols: Number of columns in matrix A + a: Ensemble perturbation/anomaly matrix (shape [nrows, ncols]) + var_obs: Observation variance + verbose: Verbosity flag + + Returns: + dict: A dictionary containing: + - weight: Localization weight + """ + try: + a_np = np.array(a, dtype=np.float64) + + weight = PDAF.local_weight( + wtype, rtype, cradius, sradius, distance, + nrows, ncols, a_np, var_obs, verbose + ) + return {"success": True, "result": {"weight": float(weight)}, "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_get_local_type", description="Get the localization type of the selected filter") +def pdaf_get_local_type() -> dict: + """ + Return the information on the localization type of the selected filter. + + Returns: + dict: A dictionary containing: + - localtype: Localization type + 0: no localization; global filter + 1: domain localization (LESTKF, LETKF, LNETF, LSEIK) + 2: covariance localization (LEnKF) + 3: covariance loc. but observation handling like domain localization (ENSRF) + """ + try: + localtype = PDAF.get_local_type() + return {"success": True, "result": {"localtype": int(localtype)}, "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_set_ens_pointer", description="Get a numpy array view of the internal ensemble array") +def pdaf_set_ens_pointer() -> dict: + """ + Return the ensemble in a numpy array with the same memory address as + PDAF's internal ensemble array, allowing for manual ensemble modification. + + Returns: + dict: A dictionary containing: + - ens_shape: Shape of the ensemble array [dim, dim_ens] + - status: Status flag + """ + try: + ens_ptr, status = PDAF.set_ens_pointer() + return { + "success": True, + "result": { + "ens_shape": list(ens_ptr.shape), + "ens": ens_ptr.tolist(), + "status": int(status) + }, + "error": None + } + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +# ============================================================================ +# Additional PDAFomi Tools +# ============================================================================ + +@mcp.tool(name="pdafomi_set_obs_err_type", description="Set observation error distribution type") +def pdafomi_set_obs_err_type(i_obs: int, obs_err_type: int) -> dict: + """ + Set the type of observation error distribution for a given observation type. + + Args: + i_obs: Index of observation type + obs_err_type: Type of observation error distribution: + 0: Gaussian (default) + 1: double exponential (Laplacian) + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAFomi.set_obs_err_type(i_obs, obs_err_type) + return {"success": True, "result": f"Observation type {i_obs} error type set to {obs_err_type}", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdafomi_set_use_global_obs", description="Set whether to use global or process-local observations") +def pdafomi_set_use_global_obs(i_obs: int, use_global_obs: int) -> dict: + """ + Set switch for using process-local or global observations. + + By default (use_global_obs=1), PDAF-OMI gathers the entire observation + vector for all processes. Setting use_global_obs=0 uses only process-local + observations, which can save computational cost. + + Args: + i_obs: Index of observation type + use_global_obs: 0: Using process-local observations + 1: Using cross-process observations (default) + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAFomi.set_use_global_obs(i_obs, use_global_obs) + return {"success": True, "result": f"Observation type {i_obs} use_global_obs set to {use_global_obs}", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdafomi_diag_obs_rmsd", description="Compute RMSD between observations and observed model state") +def pdafomi_diag_obs_rmsd(nobs: int, verbose: int) -> dict: + """ + Compute root mean squared distance between observations and observed + model state for each observation type. + + Args: + nobs: Number of observation types + verbose: Verbosity flag + + Returns: + dict: A dictionary containing: + - nobs: Number of observation types + - rmsd: Vector of RMSD values for each observation type + """ + try: + nobs_out, rmsd = PDAFomi.diag_obs_rmsd(nobs, verbose) + return { + "success": True, + "result": { + "nobs": int(nobs_out), + "rmsd": rmsd.tolist() + }, + "error": None + } + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdafomi_diag_stats", description="Compute statistics comparing observations and observed ensemble mean") +def pdafomi_diag_stats(nobs: int, verbose: int) -> dict: + """ + Compute a selection of 6 statistics comparing observations and + observed ensemble mean for each observation type. + + Statistics include: + - (1,:) correlations between observation and observed ensemble mean + - (2,:) centered RMS difference + - (3,:) mean bias (observation minus observed ensemble mean) + - (4,:) mean absolute difference + - (5,:) variance of observations + - (6,:) variance of observed ensemble mean + + Args: + nobs: Number of observation types + verbose: Verbosity flag + + Returns: + dict: A dictionary containing: + - nobs: Number of observation types + - obsstats: Array of observation statistics (shape [6, nobs]) + """ + try: + nobs_out, obsstats = PDAFomi.diag_stats(nobs, verbose) + return { + "success": True, + "result": { + "nobs": int(nobs_out), + "obsstats": obsstats.tolist() + }, + "error": None + } + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +# ============================================================================ +# Additional PDAF Setter Functions (不需要回调和MPI) +# ============================================================================ + +@mcp.tool(name="pdaf_set_comm_pdaf", description="Set the MPI communicator used by PDAF") +def pdaf_set_comm_pdaf(in_comm_pdaf: int) -> dict: + """ + Set the MPI communicator used by PDAF. + + By default, PDAF assumes it can use all available processes (MPI_COMM_WORLD). + By using this function, we limit the number of processes that can be used + by PDAF to the given MPI communicator. + + Args: + in_comm_pdaf: MPI communicator for PDAF (integer handle) + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAF.set_comm_pdaf(in_comm_pdaf) + return {"success": True, "result": f"PDAF communicator set to {in_comm_pdaf}", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_set_iparam", description="Set integer parameters for PDAF") +def pdaf_set_iparam(idval: int, value: int, flag: int = 0) -> dict: + """ + Set integer parameters for PDAF. + + This function provides an alternative way to set integer parameters + instead of providing all parameters in the call to PDAF.init. + + Args: + idval: Index of parameter + value: Parameter value + flag: Status flag input (default 0) + + Returns: + dict: A dictionary containing: + - flag: Status flag (0 for no error) + """ + try: + result = PDAF.set_iparam(idval, value, flag) + return {"success": True, "result": {"flag": int(result)}, "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_set_rparam", description="Set floating-point parameters for PDAF") +def pdaf_set_rparam(idval: int, value: float, flag: int = 0) -> dict: + """ + Set floating-point parameters for PDAF. + + This function provides an alternative way to set real parameters + instead of providing all parameters in the call to PDAF.init. + + Args: + idval: Index of parameter + value: Parameter value (float) + flag: Status flag input (default 0) + + Returns: + dict: A dictionary containing: + - flag: Status flag (0 for no error) + """ + try: + result = PDAF.set_rparam(idval, value, flag) + return {"success": True, "result": {"flag": int(result)}, "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_set_memberid", description="Set the ensemble member index to a given value") +def pdaf_set_memberid(memberid: int) -> dict: + """ + Set the ensemble member index to a given value. + + Args: + memberid: Index in the local ensemble + + Returns: + dict: A dictionary containing: + - memberid: The set member index + """ + try: + result = PDAF.set_memberid(memberid) + return {"success": True, "result": {"memberid": int(result)}, "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_set_seedset", description="Choose a seedset for the random number generator") +def pdaf_set_seedset(seedset_in: int) -> dict: + """ + Choose a seedset for the random number generator used in PDAF. + + Args: + seedset_in: Seedset index (1-20) + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAF.set_seedset(seedset_in) + return {"success": True, "result": f"Seedset set to {seedset_in}", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_get_obsmemberid", description="Get ensemble member ID when observation operator is applied") +def pdaf_get_obsmemberid(memberid: int = 0) -> dict: + """ + Return the ensemble member ID when observation operator is being applied. + + This function is used specifically for user-supplied function py__obs_op_pdaf. + + Args: + memberid: Input member ID (can be any value) + + Returns: + dict: A dictionary containing: + - memberid: Index in the local ensemble + """ + try: + result = PDAF.get_obsmemberid(memberid) + return {"success": True, "result": {"memberid": int(result)}, "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_local_weights", description="Get a vector of localization weights for given distances") +def pdaf_local_weights( + wtype: int, + cradius: float, + sradius: float, + dim: int, + distance: List[float], + verbose: int +) -> dict: + """ + Get a vector of localization weights for given distances. + + This is a vectorized version of pdaf_local_weight without regulation. + + Args: + wtype: Type of weight function: + 0: unit weight (weight=1 up to distance=cradius) + 1: exponential decrease (weight=1/e at distance=sradius) + 2: 5th order polynomial (Gaspari and Cohn 1999) + cradius: Cut-off radius where weight=0 beyond it + sradius: Support radius of localization function + dim: Size of distance and weight arrays + distance: Array of distances to observations (list of length dim) + verbose: Verbosity flag + + Returns: + dict: A dictionary containing: + - weights: Array of localization weights (list of length dim) + """ + try: + distance_np = np.array(distance, dtype=np.float64) + weights = PDAF.local_weights(wtype, cradius, sradius, dim, distance_np, verbose) + return {"success": True, "result": {"weights": weights.tolist()}, "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_diag_crps_nompi", description="Compute Continuous Ranked Probability Score without MPI") +def pdaf_diag_crps_nompi( + dim: int, + dim_ens: int, + element: int, + oens: List[List[float]], + obs: List[float] +) -> dict: + """ + Obtain a Continuous Ranked Probability Score (CRPS) for an ensemble without MPI. + + Based on Hersbach (2000) decomposition of CRPS. + + Args: + dim: Dimension of state vector + dim_ens: Ensemble size + element: ID of element to be used (0 for mean over all elements) + oens: State ensemble (2D list of shape [dim, dim_ens]) + obs: Observation/true state (list of length dim) + + Returns: + dict: A dictionary containing: + - CRPS: Continuous Ranked Probability Score + - reli: Reliability + - resol: Resolution + - uncert: Uncertainty + - status: Status flag (0=success) + """ + try: + oens_np = np.array(oens, dtype=np.float64) + obs_np = np.array(obs, dtype=np.float64) + + crps, reli, resol, uncert, status = PDAF.diag_crps_nompi( + dim, dim_ens, element, oens_np, obs_np + ) + return { + "success": True, + "result": { + "CRPS": float(crps), + "reli": float(reli), + "resol": float(resol), + "uncert": float(uncert), + "status": int(status) + }, + "error": None + } + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdaf_diag_compute_moments", description="Compute statistical moments from an ensemble") +def pdaf_diag_compute_moments( + dim_p: int, + dim_ens: int, + ens: List[List[float]], + kmax: int, + bias: int +) -> dict: + """ + Compute the mean, variance, skewness, and excess kurtosis from an ensemble. + + Args: + dim_p: PE-local state dimension + dim_ens: Ensemble size + ens: State ensemble (2D list of shape [dim_p, dim_ens]) + kmax: Maximum moment to compute (1=mean, 2=variance, 3=skewness, 4=kurtosis) + bias: 0 for unbiased estimates, 1 for biased estimates + + Returns: + dict: A dictionary containing: + - moments: Array of moments (shape [kmax, dim_p]) + """ + try: + ens_np = np.array(ens, dtype=np.float64) + moments = PDAF.diag_compute_moments(dim_p, dim_ens, ens_np, kmax, bias) + return {"success": True, "result": {"moments": moments.tolist()}, "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +# ============================================================================ +# Additional PDAFomi Setter Functions +# ============================================================================ + +@mcp.tool(name="pdafomi_set_inno_omit", description="Set innovation threshold for removing observation outliers") +def pdafomi_set_inno_omit(i_obs: int, inno_omit: float) -> dict: + """ + Set innovation threshold for removing observation outliers. + + By default, no observations are omitted. Observation omission is only + activated when inno_omit > 0.0. PDAF will omit observations where + the squared innovation of the ensemble mean is larger than the product + of inno_omit and observation error variance. + + Args: + i_obs: Index of observation type + inno_omit: Threshold of innovation to be omitted + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAFomi.set_inno_omit(i_obs, inno_omit) + return {"success": True, "result": f"Observation type {i_obs} inno_omit set to {inno_omit}", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdafomi_set_inno_omit_ivar", description="Set inverse variance for omitted observations") +def pdafomi_set_inno_omit_ivar(i_obs: int, inno_omit_ivar: float) -> dict: + """ + Set the inverse of observation error variance for omitted observations. + + This should be set to a very small value relative to assimilated observations. + By default, it is set to 1e-12. + + Args: + i_obs: Index of observation type + inno_omit_ivar: Inverse of observation variance for omitted observations + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAFomi.set_inno_omit_ivar(i_obs, inno_omit_ivar) + return {"success": True, "result": f"Observation type {i_obs} inno_omit_ivar set to {inno_omit_ivar}", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdafomi_set_domainsize", description="Set domain size for observation type") +def pdafomi_set_domainsize(i_obs: int, domainsize: List[float]) -> dict: + """ + Set the domain size for periodic boundary conditions. + + This is used when disttype is set to periodic distance calculation. + + Args: + i_obs: Index of observation type + domainsize: Domain size array (list of floats) + + Returns: + dict: A dictionary containing the success status. + """ + try: + domainsize_np = np.array(domainsize, dtype=np.float64) + PDAFomi.set_domainsize(i_obs, domainsize_np) + return {"success": True, "result": f"Observation type {i_obs} domainsize set", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdafomi_set_name", description="Set the name of an observation type") +def pdafomi_set_name(i_obs: int, name: str) -> dict: + """ + Set the name identifier for an observation type. + + This name is used in diagnostic output to identify the observation type. + + Args: + i_obs: Index of observation type + name: Name string for the observation type + + Returns: + dict: A dictionary containing the success status. + """ + try: + PDAFomi.set_name(i_obs, name) + return {"success": True, "result": f"Observation type {i_obs} name set to '{name}'", "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdafomi_diag_get_obs", description="Get observation vector and coordinates for an observation type") +def pdafomi_diag_get_obs(id_obs: int) -> dict: + """ + Get observation vector and corresponding coordinates for specified observation type. + + Args: + id_obs: Index of observation type to return + + Returns: + dict: A dictionary containing: + - dim_obs_diag: Observation dimension + - ncoord: Number of observation dimensions + - obs_p: Observation vector + - ocoord_p: Coordinate array + """ + try: + dim_obs_diag, ncoord, obs_p, ocoord_p = PDAFomi.diag_get_obs(id_obs) + return { + "success": True, + "result": { + "dim_obs_diag": int(dim_obs_diag), + "ncoord": int(ncoord), + "obs_p": obs_p.tolist(), + "ocoord_p": ocoord_p.tolist() + }, + "error": None + } + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdafomi_diag_get_hxmean", description="Get observed ensemble mean for an observation type") +def pdafomi_diag_get_hxmean(id_obs: int) -> dict: + """ + Get observed ensemble mean for a given observation type. + + Args: + id_obs: Index of observation type to return + + Returns: + dict: A dictionary containing: + - dim_obs_diag: Observation dimension + - hxmean_p: Observed ensemble mean + """ + try: + dim_obs_diag, hxmean_p = PDAFomi.diag_get_hxmean(id_obs) + return { + "success": True, + "result": { + "dim_obs_diag": int(dim_obs_diag), + "hxmean_p": hxmean_p.tolist() + }, + "error": None + } + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +@mcp.tool(name="pdafomi_diag_get_ivar", description="Get inverse observation error variance for an observation type") +def pdafomi_diag_get_ivar(id_obs: int) -> dict: + """ + Get inverse of observation error variance for a given observation type. + + Args: + id_obs: Index of observation type to return + + Returns: + dict: A dictionary containing: + - dim_obs_diag: Observation dimension + - ivar: Inverse observation error variances + """ + try: + dim_obs_diag, ivar = PDAFomi.diag_get_ivar(id_obs) + return { + "success": True, + "result": { + "dim_obs_diag": int(dim_obs_diag), + "ivar": ivar.tolist() + }, + "error": None + } + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +# ============================================================================ +# Utility Functions +# ============================================================================ + +@mcp.tool(name="get_pdaf_module_info", description="Get information about available pyPDAF modules and their functions") +def get_pdaf_module_info() -> dict: + """ + Get information about available pyPDAF modules and their main functions. + + Returns: + dict: A dictionary containing module information. + """ + try: + info = { + "PDAF": { + "description": "Core PDAF module with filter functions and utilities", + "main_functions": [ + "correlation_function", "deallocate", "eofcovar", "force_analysis", + "get_fcst_info", "print_filter_types", "print_da_types", "print_info", + "reset_forget", "set_debug_flag", "set_offline_mode", "sample_ens", + "local_weight", "local_weights", "set_ens_pointer", + "get_assim_flag", "get_localfilter", "get_local_type", "get_memberid", + "diag_ensmean", "diag_stddev_nompi", "diag_stddev", + "diag_variance_nompi", "diag_variance", + "diag_rmsd_nompi", "diag_rmsd", + "diag_effsample", "diag_ensstats", "diag_compute_moments" + ] + }, + "PDAF3": { + "description": "PDAF3 module with initialization and assimilation functions", + "main_functions": [ + "init", "init_forecast", "set_parallel", + "assimilate", "assim_offline", + "assimilate_3dvar_all", "assim_offline_3dvar_all", + "assimilate_local_nondiagr", "assimilate_global_nondiagr", + "generate_obs", "generate_obs_offline" + ] + }, + "PDAFomi": { + "description": "PDAF Observation Module Interface for flexible observation handling", + "main_functions": [ + "init", "init_local", "check_error", "gather_obs", + "set_debug_flag", "set_doassim", "set_disttype", "set_ncoord", + "set_obs_err_type", "set_use_global_obs", + "set_inno_omit", "set_inno_omit_ivar", + "diag_nobstypes", "diag_dimobs", "diag_obs_rmsd", "diag_stats", + "diag_get_hx", "diag_get_hxmean", "diag_get_obs" + ] + }, + "PDAFlocal": { + "description": "PDAF local analysis module for domain localization", + "main_functions": [ + "set_indices", "set_increment_weights", "clear_increment_weights" + ] + }, + "PDAFlocalomi": { + "description": "PDAF local analysis with OMI observation handling", + "main_functions": [] + } + } + return {"success": True, "result": info, "error": None} + except Exception as e: + return {"success": False, "result": None, "error": str(e)} + + +def create_app() -> FastMCP: + """ + Creates and returns the FastMCP application instance. + + Returns: + FastMCP: The FastMCP application instance. + """ + return mcp \ No newline at end of file diff --git a/pyPDAF/mcp_output/requirements.txt b/pyPDAF/mcp_output/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..dde114a933b7bd22ac7d74742832b07a8ea9353e --- /dev/null +++ b/pyPDAF/mcp_output/requirements.txt @@ -0,0 +1,2 @@ +fastmcp>=0.1.0 +pydantic>=2.0.0 diff --git a/pyPDAF/mcp_output/simple_revise_error_analysis.json b/pyPDAF/mcp_output/simple_revise_error_analysis.json new file mode 100644 index 0000000000000000000000000000000000000000..c9d5377b570d497803891164342a674b412afe0b --- /dev/null +++ b/pyPDAF/mcp_output/simple_revise_error_analysis.json @@ -0,0 +1,6 @@ +{ + "status": "FAIL", + "next_action": "fix_directly", + "confidence": 0.9, + "summary": "The error is due to a missing Python module 'mpi4py'. This can be fixed directly by installing the missing module. Use the command 'conda install mpi4py' or 'pip install mpi4py' within the appropriate conda environment to resolve the issue. Ensure that the environment where the script is being executed has access to the 'mpi4py' module." +} \ No newline at end of file diff --git a/pyPDAF/mcp_output/start_mcp.py b/pyPDAF/mcp_output/start_mcp.py new file mode 100644 index 0000000000000000000000000000000000000000..423ec23c94b11f5462dcbf5b0fb6d2b2a1db60c6 --- /dev/null +++ b/pyPDAF/mcp_output/start_mcp.py @@ -0,0 +1,33 @@ +""" +MCP Service Startup Entry +""" +import sys +import os + +project_root = os.path.dirname(os.path.abspath(__file__)) +mcp_plugin_dir = os.path.join(project_root, "mcp_plugin") +if mcp_plugin_dir not in sys.path: + sys.path.insert(0, mcp_plugin_dir) + +# Set path to source directory +source_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "source", "src") +sys.path.insert(0, source_path) + +from mcp_service import create_app + +def main(): + """Start FastMCP service""" + app = create_app() + # Use environment variable to configure port, default 8000 + port = int(os.environ.get("MCP_PORT", "8000")) + + # Choose transport mode based on environment variable + transport = os.environ.get("MCP_TRANSPORT", "stdio") + if transport == "http": + app.run(transport="http", host="0.0.0.0", port=port) + else: + # Default to STDIO mode + app.run() + +if __name__ == "__main__": + main() diff --git a/pyPDAF/mcp_output/tests_mcp/test_mcp_basic.py b/pyPDAF/mcp_output/tests_mcp/test_mcp_basic.py new file mode 100644 index 0000000000000000000000000000000000000000..cfa9b36554276548850db7754ed047b24a344402 --- /dev/null +++ b/pyPDAF/mcp_output/tests_mcp/test_mcp_basic.py @@ -0,0 +1,49 @@ +""" +MCP Service Basic Test +""" +import sys +import os + +project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +mcp_plugin_dir = os.path.join(project_root, "mcp_plugin") +if mcp_plugin_dir not in sys.path: + sys.path.insert(0, mcp_plugin_dir) + +source_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "source") +sys.path.insert(0, source_path) + +def test_import_mcp_service(): + """Test if MCP service can be imported normally""" + try: + from mcp_service import create_app + app = create_app() + assert app is not None + print("MCP service imported successfully") + return True + except Exception as e: + print("MCP service import failed: " + str(e)) + return False + +def test_adapter_init(): + """Test if adapter can be initialized normally""" + try: + from adapter import Adapter + adapter = Adapter() + assert adapter is not None + print("Adapter initialized successfully") + return True + except Exception as e: + print("Adapter initialization failed: " + str(e)) + return False + +if __name__ == "__main__": + print("Running MCP service basic test...") + test1 = test_import_mcp_service() + test2 = test_adapter_init() + + if test1 and test2: + print("All basic tests passed") + sys.exit(0) + else: + print("Some tests failed") + sys.exit(1) diff --git a/pyPDAF/mcp_output/tests_smoke/test_smoke.py b/pyPDAF/mcp_output/tests_smoke/test_smoke.py new file mode 100644 index 0000000000000000000000000000000000000000..6d64007223af2c8be8ff77bc28c4b9f857895d9c --- /dev/null +++ b/pyPDAF/mcp_output/tests_smoke/test_smoke.py @@ -0,0 +1,29 @@ +import importlib, sys +import os + +# Add current directory to Python path +sys.path.insert(0, os.getcwd()) + +source_dir = os.path.join(os.getcwd(), "source") +if os.path.exists(source_dir): + sys.path.insert(0, source_dir) + + +try: + importlib.import_module("src.pyPDAF") + print("OK - Successfully imported src.pyPDAF") +except ImportError as e: + print(f"Failed to import src.pyPDAF: {e}") + fallback_packages = [] + + fallback_packages = ['pyPDAF', 'src.pyPDAF'] + + for pkg in fallback_packages: + try: + importlib.import_module(pkg) + print(f"OK - Successfully imported {pkg}") + break + except ImportError: + continue + else: + print("All import attempts failed") diff --git a/pyPDAF/source/.github/workflows/conda_build_linux.yaml b/pyPDAF/source/.github/workflows/conda_build_linux.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8e74ffcef7b3ee5bb9cc820b6d2b25655c814966 --- /dev/null +++ b/pyPDAF/source/.github/workflows/conda_build_linux.yaml @@ -0,0 +1,31 @@ +name: conda_build_linux +on: [workflow_dispatch] +jobs: + upload_conda_linux: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: 'true' + + - uses: conda-incubator/setup-miniconda@v3 + with: + auto-activate-base: true + auto-update-conda: true + activate-environment: "" + + - name: install pyPDAF + shell: bash -el {0} + run: | + conda install python anaconda-client conda-build conda-verify + anaconda logout --at anaconda.org + anaconda login --at anaconda.org --hostname "$GITHUB_RUN_ID-$GITHUB_RUN_NUMBER" --username yumengch --password ${{ secrets.ANACONDA }} + conda config --set anaconda_upload yes + conda-build -c conda-forge conda.recipe/ + conda install -y -c conda-forge --use-local pypdaf + cd example + mpiexec -n 4 python -u online/main.py + + - name: Setup tmate session + if: ${{ failure() }} + uses: mxschmitt/action-tmate@v3 diff --git a/pyPDAF/source/.github/workflows/conda_build_mac_intel.yaml b/pyPDAF/source/.github/workflows/conda_build_mac_intel.yaml new file mode 100644 index 0000000000000000000000000000000000000000..49c3f81035a29b5367942511581811f32b1204be --- /dev/null +++ b/pyPDAF/source/.github/workflows/conda_build_mac_intel.yaml @@ -0,0 +1,34 @@ +name: conda_build_mac_intel +on: [workflow_dispatch] +jobs: + upload_conda_mac_intel: + runs-on: macos-15-intel + steps: + - uses: actions/checkout@v4 + with: + submodules: 'true' + + - uses: conda-incubator/setup-miniconda@v3 + with: + auto-activate-base: true + auto-update-conda: true + activate-environment: "" + + - name: build pyPDAF + shell: bash -el {0} + run: | + conda install python anaconda-client conda-build conda-verify + anaconda login --at anaconda.org --username yumengch --password ${{ secrets.ANACONDA }} + conda config --set anaconda_upload yes + conda-build -c conda-forge conda.recipe/ + + - name: install pyPDAF + shell: bash -el {0} + run: | + conda install -y -c conda-forge --use-local pypdaf + cd example + mpiexec -n 4 python -u online/main.py + + - name: Setup tmate session + if: ${{ failure() }} + uses: mxschmitt/action-tmate@v3 diff --git a/pyPDAF/source/.github/workflows/conda_build_mac_m1.yaml b/pyPDAF/source/.github/workflows/conda_build_mac_m1.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fccd34eaf62b53c9a84f8def89ef5639d453c8df --- /dev/null +++ b/pyPDAF/source/.github/workflows/conda_build_mac_m1.yaml @@ -0,0 +1,34 @@ +name: conda_build_mac_m1 +on: [workflow_dispatch] +jobs: + upload_conda_mac_m1: + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: 'true' + + - uses: conda-incubator/setup-miniconda@v3 + with: + auto-activate-base: true + auto-update-conda: true + activate-environment: "" + + - name: build pyPDAF + shell: bash -el {0} + run: | + conda install python anaconda-client conda-build conda-verify + anaconda login --at anaconda.org --username yumengch --password ${{ secrets.ANACONDA }} + conda config --set anaconda_upload yes + conda-build -c conda-forge conda.recipe/ + + - name: install pyPDAF + shell: bash -el {0} + run: | + conda install -y -c conda-forge --use-local pypdaf + cd example + mpiexec -n 4 python -u online/main.py + + - name: Setup tmate session + if: ${{ failure() }} + uses: mxschmitt/action-tmate@v3 diff --git a/pyPDAF/source/.github/workflows/conda_build_win.yaml b/pyPDAF/source/.github/workflows/conda_build_win.yaml new file mode 100644 index 0000000000000000000000000000000000000000..dc140951f56b4943b739f7f96d856a3efe0317d1 --- /dev/null +++ b/pyPDAF/source/.github/workflows/conda_build_win.yaml @@ -0,0 +1,45 @@ +name: conda_build_win +on: [workflow_dispatch] +jobs: + upload_conda_win: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: 'true' + + - uses: conda-incubator/setup-miniconda@v3 + with: + auto-activate-base: true + activate-environment: "" + + - name: setup anaconda + shell: cmd /C CALL {0} + run: | + conda install -n base python anaconda-client conda-build conda-verify + + + - name: anaconda login + shell: cmd /C CALL {0} + run: | + call conda activate base + anaconda login --at anaconda.org --hostname "$GITHUB_RUN_ID-$GITHUB_RUN_NUMBER" --username yumengch --password ${{ secrets.ANACONDA }} + + - name: set anaconda upload + shell: cmd /C CALL {0} + run: | + call conda activate base + conda config --set anaconda_upload yes + + - name: build pyPDAF + shell: cmd /C CALL {0} + run: | + call conda activate base + conda build -c conda-forge conda.recipe/ + conda install -y -c conda-forge --use-local pypdaf + cd example + mpiexec -n 4 python -u online/main.py + + - name: Setup tmate session + if: ${{ failure() }} + uses: mxschmitt/action-tmate@v3 diff --git a/pyPDAF/source/.gitignore b/pyPDAF/source/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..f62b1056403de22e7fb253280d7ee14622d8144e --- /dev/null +++ b/pyPDAF/source/.gitignore @@ -0,0 +1,138 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +*.o +*.mod +*.pyc +*.npz +*.a +*.c +docs/build/ +docs/source/_autosummary \ No newline at end of file diff --git a/pyPDAF/source/.gitmodules b/pyPDAF/source/.gitmodules new file mode 100644 index 0000000000000000000000000000000000000000..4b1abbb241f20d4c6d3e0cfe5b5318fcdf15e2c3 --- /dev/null +++ b/pyPDAF/source/.gitmodules @@ -0,0 +1,4 @@ +[submodule "PDAF"] + branch = PDAF_V3.0 + path = PDAF + url = https://github.com/PDAF/PDAF.git diff --git a/pyPDAF/source/LICENSE b/pyPDAF/source/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..f288702d2fa16d3cdf0035b15a9fcbc552cd88e7 --- /dev/null +++ b/pyPDAF/source/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/pyPDAF/source/README.md b/pyPDAF/source/README.md new file mode 100644 index 0000000000000000000000000000000000000000..21954c9f211fd58097fbbb31d7ce459c9fb4c376 --- /dev/null +++ b/pyPDAF/source/README.md @@ -0,0 +1,94 @@ +# pyPDAF - A Python interface to the Fortran-written data assimilation library + +pyPDAF provides a Python interface to the established +[Parallel Data Assimilation Framework (PDAF)](https://pdaf.awi.de/trac/wiki). +The original framework is used with various regional and global +climate models including atmosphere, ocean, hydrology, land surface +and sea ice models. These models are typically written in Fortran +which can be easily used with PDAF. pyPDAF can become useful +in the following scenarios: +- With an increasing number of Python-coded numerical models, + especially machine learning models, pyPDAF is a convenient tool + to implement data assimilation (DA) systems purely in Python. +- Alternatively, pyPDAF can be used to set up offline + data assimilation system. In such a system, the model fields in + restart files are replaced by analyses generated by pyPDAF. + This can be an attractive alternative to the original Fortran + implementations considering the simplicity of code implementation + and package management in Python. + +The interface inherits the efficiency of the data assimilation +algorithms in Fortran, and the flexibility to be applied to different +models and observations. This means that users of pyPDAF can couple +the DA algorithms with any types of model and observations without +the need to coding the actual DA algorithms. This allows the users +to focus on the specific research problems. The framework includes +various ensemble DA algorithms including many variants of ensemble +Kalman filters, particle filters and other non-linear filters. +It also provides framework for variants of 3DVar. A full list of +supported methods can be found +[here](https://pdaf.awi.de/trac/wiki/AvailableOptionsforInitPDAF) + +## Getting Started +It is recommended to install pyPDAF via `conda`: +```bash +conda create -n pypdaf -c conda-forge yumengch::pypdaf +``` +You can also install from the source code using `pip` and `meson`. One can +find the information in . + +## Building a DA system with pyPDAF +To construct a data assimilation system, only 7 pyPDAF functions are necessary: +### Initialise PDAF + - pyPDAF.set_parallel - one can omit it without parallelisation + - pyPDAF.init + - pyPDAF.PDAFomi.init + - pyPDAF.PDAFomi.init_local - only used in domain localisation + - pyPDAF.PDAFomi.set_domain_limits - only used in domain localisation + - pyPDAF.init_forecast + +### Data assimilation + - pyPDAF.assimilate + +### Finalise PDAF + - pyPDAF.deallocate + +However, users have to implement user-supplied functions to provide state vector +and observation information. + +For users without prior experience with PDAF, we highly recommend to +start with the tutorial here: +[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/yumengch/pyPDAF/). + +To construct a parallel ensemble DA system, +in [example](example) directory, we provide both `online` +and `offline` examples. +pyPDAF and PDAF both utilise `Message Passing Interface (MPI)` +parallelisation. Hence, to run the example, it needs to be executed +from commandline using `mpiexec`. For example, +```bash +cd example +mpiexec -n 4 python -u online/main.py +``` +will run the example with 4 processes. +The example is based on +the [tutorials](http://pdaf.awi.de/trac/wiki/FirstSteps) of the original PDAF. + + +## Documentation: +The most up-to-date pyPDAF has interface with ```PDAF-V3.0```. +A [documentation](https://yumengch.github.io/pyPDAF/index.html) is provided. +The interface follows the naming convention of PDAF. We divide PDAF subroutines +into several subpackages including `PDAF`, `PDAF3`, `PDAFomi`, `PDAFlocal`, and +`PDAFlocalomi`. These provide + + +## Having questions? +We welcome issues, pull requests, feature requests and any other discussions in the issues section. + +## Contributors: +Yumeng Chen, Lars Nerger + +pyPDAF is mainly developed and maintained by National Centre for Earth Observation and University of Reading. + + diff --git a/pyPDAF/source/__init__.py b/pyPDAF/source/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b8e524f40cbdd24247672b4afe77fe85e4e20970 --- /dev/null +++ b/pyPDAF/source/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +""" +pyPDAF Project Package Initialization File +""" diff --git a/pyPDAF/source/build/cp310/.gitignore b/pyPDAF/source/build/cp310/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..34a6c661a99b0aa15d36813f7e4293304a640e54 --- /dev/null +++ b/pyPDAF/source/build/cp310/.gitignore @@ -0,0 +1,3 @@ + +# This file is generated by meson-python. It will not be recreated if deleted or modified. +* diff --git a/pyPDAF/source/build/cp310/.hgignore b/pyPDAF/source/build/cp310/.hgignore new file mode 100644 index 0000000000000000000000000000000000000000..0dbf8de2ea767eb7ee54ace72f69dc64bbde215a --- /dev/null +++ b/pyPDAF/source/build/cp310/.hgignore @@ -0,0 +1,4 @@ + +# This file is generated by meson-python. It will not be recreated if deleted or modified. +syntax: glob +**/* diff --git a/pyPDAF/source/build/cp310/meson-info/meson-info.json b/pyPDAF/source/build/cp310/meson-info/meson-info.json new file mode 100644 index 0000000000000000000000000000000000000000..802f537f0eeee60782a4e9b38697de2a19b75750 --- /dev/null +++ b/pyPDAF/source/build/cp310/meson-info/meson-info.json @@ -0,0 +1 @@ +{"meson_version": {"full": "1.10.0", "major": 1, "minor": 10, "patch": 0}, "directories": {"source": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source", "build": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310", "info": "/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-info"}, "introspection": {"version": {"full": "1.0.0", "major": 1, "minor": 0, "patch": 0}, "information": {"benchmarks": {"file": "intro-benchmarks.json", "updated": false}, "buildoptions": {"file": "intro-buildoptions.json", "updated": false}, "buildsystem_files": {"file": "intro-buildsystem_files.json", "updated": false}, "compilers": {"file": "intro-compilers.json", "updated": false}, "dependencies": {"file": "intro-dependencies.json", "updated": false}, "installed": {"file": "intro-installed.json", "updated": false}, "install_plan": {"file": "intro-install_plan.json", "updated": false}, "machines": {"file": "intro-machines.json", "updated": false}, "projectinfo": {"file": "intro-projectinfo.json", "updated": false}, "targets": {"file": "intro-targets.json", "updated": false}, "tests": {"file": "intro-tests.json", "updated": false}}}, "build_files_updated": false, "error": true, "error_list": ["File PDAF/src/PDAF3_init.F90 does not exist."]} \ No newline at end of file diff --git a/pyPDAF/source/build/cp310/meson-logs/meson-log.txt b/pyPDAF/source/build/cp310/meson-logs/meson-log.txt new file mode 100644 index 0000000000000000000000000000000000000000..d1250f0e538b3d77c622cd0a5409f95daa5a8d56 --- /dev/null +++ b/pyPDAF/source/build/cp310/meson-logs/meson-log.txt @@ -0,0 +1,505 @@ +Build started at 2025-12-09T23:43:18.387370 +Main binary: /home/wshiah/code/miniconda3/envs/pyPDAF_294797_env/bin/python3.10 +Build Options: -Dbuildtype=release -Db_ndebug=if-release -Db_vscrt=md --native-file=/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-python-native-file.ini +Python system: Linux +The Meson build system +Version: 1.10.0 +Source dir: /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source +Build dir: /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310 +Build type: native build +Project name: pyPDAF +Project version: 1.0.4 +----------- +Detecting compiler via: `gfortran --help` -> 0 +stdout: +Usage: gfortran [options] file... +Options: + -pass-exit-codes Exit with highest error code from a phase. + --help Display this information. + --target-help Display target specific command line options. + --help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...]. + Display specific types of command line options. + (Use '-v --help' to display command line options of sub-processes). + --version Display compiler version information. + -dumpspecs Display all of the built in spec strings. + -dumpversion Display the version of the compiler. + -dumpmachine Display the compiler's target processor. + -print-search-dirs Display the directories in the compiler's search path. + -print-libgcc-file-name Display the name of the compiler's companion library. + -print-file-name= Display the full path to library . + -print-prog-name= Display the full path to compiler component . + -print-multiarch Display the target's normalized GNU triplet, used as + a component in the library path. + -print-multi-directory Display the root directory for versions of libgcc. + -print-multi-lib Display the mapping between command line options and + multiple library search directories. + -print-multi-os-directory Display the relative path to OS libraries. + -print-sysroot Display the target libraries directory. + -print-sysroot-headers-suffix Display the sysroot suffix used to find headers. + -Wa, Pass comma-separated on to the assembler. + -Wp, Pass comma-separated on to the preprocessor. + -Wl, Pass comma-separated on to the linker. + -Xassembler Pass on to the assembler. + -Xpreprocessor Pass on to the preprocessor. + -Xlinker Pass on to the linker. + -save-temps Do not delete intermediate files. + -save-temps= Do not delete intermediate files. + -no-canonical-prefixes Do not canonicalize paths when building relative + prefixes to other gcc components. + -pipe Use pipes rather than intermediate files. + -time Time the execution of each subprocess. + -specs= Override built-in specs with the contents of . + -std= Assume that the input sources are for . + --sysroot= Use as the root directory for headers + and libraries. + -B Add to the compiler's search paths. + -v Display the programs invoked by the compiler. + -### Like -v but options quoted and commands not executed. + -E Preprocess only; do not compile, assemble or link. + -S Compile only; do not assemble or link. + -c Compile and assemble, but do not link. + -o Place the output into . + -pie Create a dynamically linked position independent + executable. + -shared Create a shared library. + -x Specify the language of the following input files. + Permissible languages include: c c++ assembler none + 'none' means revert to the default behavior of + guessing the language based on the file's extension. + +Options starting with -g, -f, -m, -O, -W, or --param are automatically + passed on to the various sub-processes invoked by gfortran. In order to pass + other options on to these processes the -W options must be used. + +For bug reporting instructions, please see: +. +----------- +----------- +Detecting compiler via: `gfortran --version` -> 0 +stdout: +GNU Fortran (Ubuntu 11.4.0-1ubuntu1~22.04.2) 11.4.0 +Copyright (C) 2021 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +----------- +pre-processor extraction using -cpp -x fortran failed, falling back w/o lang +Running command: -E -dM - +----- +----------- +Detecting linker via: `gfortran -Wl,--version` -> 0 +stdout: +GNU ld (GNU Binutils for Ubuntu) 2.38 +Copyright (C) 2022 Free Software Foundation, Inc. +This program is free software; you may redistribute it under the terms of +the GNU General Public License version 3 or (at your option) a later version. +This program has absolutely no warranty. +----------- +stderr: +collect2 version 11.4.0 +/usr/bin/ld -plugin /usr/lib/gcc/x86_64-linux-gnu/11/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper -plugin-opt=-fresolution=/ssddata/shiweijie/tmp/ccN6AZcP.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/11/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/11 -L/usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/11/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/11/../../.. --version -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/11/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/crtn.o +----------- +Sanity testing Fortran compiler: gfortran +Is cross compiler: False. +Sanity check compiler command line: gfortran sanitycheckf.f -o sanitycheckf.exe +Sanity check compile stdout: + +----- +Sanity check compile stderr: + +----- +Running test binary command: /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/sanitycheckf.exe +----------- +Sanity check: `/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/sanitycheckf.exe` -> 0 +stdout: +Fortran compilation is working. +----------- +Fortran compiler for the host machine: gfortran (gcc 11.4.0 "GNU Fortran (Ubuntu 11.4.0-1ubuntu1~22.04.2) 11.4.0") +Fortran linker for the host machine: gfortran ld.bfd 2.38 +----------- +Detecting archiver via: `gcc-ar --version` -> 0 +stdout: +GNU ar (GNU Binutils for Ubuntu) 2.38 +Copyright (C) 2022 Free Software Foundation, Inc. +This program is free software; you may redistribute it under the terms of +the GNU General Public License version 3 or (at your option) any later version. +This program has absolutely no warranty. +----------- +----------- +Detecting compiler via: `cc --version` -> 0 +stdout: +cc (Ubuntu 12.3.0-1ubuntu1~22.04.2) 12.3.0 +Copyright (C) 2022 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +----------- +Running command: -cpp -x c -E -dM - +----- +----------- +Detecting linker via: `cc -Wl,--version` -> 0 +stdout: +GNU ld (GNU Binutils for Ubuntu) 2.38 +Copyright (C) 2022 Free Software Foundation, Inc. +This program is free software; you may redistribute it under the terms of +the GNU General Public License version 3 or (at your option) a later version. +This program has absolutely no warranty. +----------- +stderr: +collect2 version 12.3.0 +/usr/bin/ld -plugin /usr/lib/gcc/x86_64-linux-gnu/12/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/12/lto-wrapper -plugin-opt=-fresolution=/ssddata/shiweijie/tmp/cciVQTKq.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/12/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/12 -L/usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/12/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/12/../../.. --version -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/12/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/crtn.o +----------- +Sanity testing C compiler: /usr/bin/ccache cc +Is cross compiler: False. +Sanity check compiler command line: /usr/bin/ccache cc sanitycheckc.c -o sanitycheckc.exe -D_FILE_OFFSET_BITS=64 +Sanity check compile stdout: + +----- +Sanity check compile stderr: + +----- +Running test binary command: /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/sanitycheckc.exe +----------- +Sanity check: `/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/sanitycheckc.exe` -> 0 +C compiler for the host machine: /usr/bin/ccache cc (gcc 12.3.0 "cc (Ubuntu 12.3.0-1ubuntu1~22.04.2) 12.3.0") +C linker for the host machine: cc ld.bfd 2.38 +----------- +Detecting compiler via: `cython -V` -> 0 +stdout: +Cython version 3.2.2 +----------- +stderr: +Cython version 3.2.2 +----------- +Running compile: +Working directory: /ssddata/shiweijie/tmp/tmphfa7z9tr +Code: +print("hello world") +----------- +Command line: `cython /ssddata/shiweijie/tmp/tmphfa7z9tr/testfile.pyx -o /ssddata/shiweijie/tmp/tmphfa7z9tr/output.exe --fast-fail` -> 0 +Cython compiler for the host machine: cython (cython 3.2.2) +----------- +Detecting compiler via: `gfortran --help` -> 0 +stdout: +Usage: gfortran [options] file... +Options: + -pass-exit-codes Exit with highest error code from a phase. + --help Display this information. + --target-help Display target specific command line options. + --help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...]. + Display specific types of command line options. + (Use '-v --help' to display command line options of sub-processes). + --version Display compiler version information. + -dumpspecs Display all of the built in spec strings. + -dumpversion Display the version of the compiler. + -dumpmachine Display the compiler's target processor. + -print-search-dirs Display the directories in the compiler's search path. + -print-libgcc-file-name Display the name of the compiler's companion library. + -print-file-name= Display the full path to library . + -print-prog-name= Display the full path to compiler component . + -print-multiarch Display the target's normalized GNU triplet, used as + a component in the library path. + -print-multi-directory Display the root directory for versions of libgcc. + -print-multi-lib Display the mapping between command line options and + multiple library search directories. + -print-multi-os-directory Display the relative path to OS libraries. + -print-sysroot Display the target libraries directory. + -print-sysroot-headers-suffix Display the sysroot suffix used to find headers. + -Wa, Pass comma-separated on to the assembler. + -Wp, Pass comma-separated on to the preprocessor. + -Wl, Pass comma-separated on to the linker. + -Xassembler Pass on to the assembler. + -Xpreprocessor Pass on to the preprocessor. + -Xlinker Pass on to the linker. + -save-temps Do not delete intermediate files. + -save-temps= Do not delete intermediate files. + -no-canonical-prefixes Do not canonicalize paths when building relative + prefixes to other gcc components. + -pipe Use pipes rather than intermediate files. + -time Time the execution of each subprocess. + -specs= Override built-in specs with the contents of . + -std= Assume that the input sources are for . + --sysroot= Use as the root directory for headers + and libraries. + -B Add to the compiler's search paths. + -v Display the programs invoked by the compiler. + -### Like -v but options quoted and commands not executed. + -E Preprocess only; do not compile, assemble or link. + -S Compile only; do not assemble or link. + -c Compile and assemble, but do not link. + -o Place the output into . + -pie Create a dynamically linked position independent + executable. + -shared Create a shared library. + -x Specify the language of the following input files. + Permissible languages include: c c++ assembler none + 'none' means revert to the default behavior of + guessing the language based on the file's extension. + +Options starting with -g, -f, -m, -O, -W, or --param are automatically + passed on to the various sub-processes invoked by gfortran. In order to pass + other options on to these processes the -W options must be used. + +For bug reporting instructions, please see: +. +----------- +----------- +Detecting compiler via: `gfortran --version` -> 0 +stdout: +GNU Fortran (Ubuntu 11.4.0-1ubuntu1~22.04.2) 11.4.0 +Copyright (C) 2021 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +----------- +pre-processor extraction using -cpp -x fortran failed, falling back w/o lang +Running command: -E -dM - +----- +----------- +Detecting linker via: `gfortran -Wl,--version` -> 0 +stdout: +GNU ld (GNU Binutils for Ubuntu) 2.38 +Copyright (C) 2022 Free Software Foundation, Inc. +This program is free software; you may redistribute it under the terms of +the GNU General Public License version 3 or (at your option) a later version. +This program has absolutely no warranty. +----------- +stderr: +collect2 version 11.4.0 +/usr/bin/ld -plugin /usr/lib/gcc/x86_64-linux-gnu/11/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper -plugin-opt=-fresolution=/ssddata/shiweijie/tmp/ccCNrRnf.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/11/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/11 -L/usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/11/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/11/../../.. --version -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/11/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/crtn.o +----------- +Sanity testing Fortran compiler: gfortran +Is cross compiler: False. +Sanity check compiler command line: gfortran sanitycheckf.f -o sanitycheckf.exe +Sanity check compile stdout: + +----- +Sanity check compile stderr: + +----- +Running test binary command: /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/sanitycheckf.exe +----------- +Sanity check: `/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/sanitycheckf.exe` -> 0 +stdout: +Fortran compilation is working. +----------- +Fortran compiler for the build machine: gfortran (gcc 11.4.0 "GNU Fortran (Ubuntu 11.4.0-1ubuntu1~22.04.2) 11.4.0") +Fortran linker for the build machine: gfortran ld.bfd 2.38 +----------- +Detecting archiver via: `gcc-ar --version` -> 0 +stdout: +GNU ar (GNU Binutils for Ubuntu) 2.38 +Copyright (C) 2022 Free Software Foundation, Inc. +This program is free software; you may redistribute it under the terms of +the GNU General Public License version 3 or (at your option) any later version. +This program has absolutely no warranty. +----------- +----------- +Detecting compiler via: `cc --version` -> 0 +stdout: +cc (Ubuntu 12.3.0-1ubuntu1~22.04.2) 12.3.0 +Copyright (C) 2022 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +----------- +Running command: -cpp -x c -E -dM - +----- +----------- +Detecting linker via: `cc -Wl,--version` -> 0 +stdout: +GNU ld (GNU Binutils for Ubuntu) 2.38 +Copyright (C) 2022 Free Software Foundation, Inc. +This program is free software; you may redistribute it under the terms of +the GNU General Public License version 3 or (at your option) a later version. +This program has absolutely no warranty. +----------- +stderr: +collect2 version 12.3.0 +/usr/bin/ld -plugin /usr/lib/gcc/x86_64-linux-gnu/12/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/12/lto-wrapper -plugin-opt=-fresolution=/ssddata/shiweijie/tmp/ccPANPFY.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/12/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/12 -L/usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/12/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/12/../../.. --version -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/12/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/crtn.o +----------- +Sanity testing C compiler: /usr/bin/ccache cc +Is cross compiler: False. +Sanity check compiler command line: /usr/bin/ccache cc sanitycheckc.c -o sanitycheckc.exe -D_FILE_OFFSET_BITS=64 +Sanity check compile stdout: + +----- +Sanity check compile stderr: + +----- +Running test binary command: /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/sanitycheckc.exe +----------- +Sanity check: `/export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/sanitycheckc.exe` -> 0 +C compiler for the build machine: /usr/bin/ccache cc (gcc 12.3.0 "cc (Ubuntu 12.3.0-1ubuntu1~22.04.2) 12.3.0") +C linker for the build machine: cc ld.bfd 2.38 +----------- +Detecting compiler via: `cython -V` -> 0 +stdout: +Cython version 3.2.2 +----------- +stderr: +Cython version 3.2.2 +----------- +Using cached compile: +Cached command line: cython /ssddata/shiweijie/tmp/tmphfa7z9tr/testfile.pyx -o /ssddata/shiweijie/tmp/tmphfa7z9tr/output.exe --fast-fail + +Code: + print("hello world") +Cached compiler stdout: + +Cached compiler stderr: + +Cython compiler for the build machine: cython (cython 3.2.2) +Build machine cpu family: x86_64 +Build machine cpu: x86_64 +Host machine cpu family: x86_64 +Host machine cpu: x86_64 +Target machine cpu family: x86_64 +Target machine cpu: x86_64 +Program python found: YES (/home/wshiah/code/miniconda3/envs/pyPDAF_294797_env/bin/python3.10) +Searching for '/home/wshiah/code/miniconda3/envs/pyPDAF_294797_env/lib/pkgconfig' via pkgconfig lookup in LIBPC +Pkg-config binary missing from cross or native file, or env var undefined. +Trying a default Pkg-config fallback at pkg-config +Found pkg-config: YES (/usr/bin/pkg-config) 0.29.2 +Determining dependency 'python-3.10' with pkg-config executable '/usr/bin/pkg-config' +env[PKG_CONFIG_PATH]: /home/wshiah/code/miniconda3/envs/pyPDAF_294797_env/lib/pkgconfig +env[PKG_CONFIG]: /usr/bin/pkg-config +----------- +Called: `/usr/bin/pkg-config --modversion python-3.10` -> 0 +stdout: +3.10 +----------- +env[PKG_CONFIG_PATH]: /home/wshiah/code/miniconda3/envs/pyPDAF_294797_env/lib/pkgconfig +env[PKG_CONFIG]: /usr/bin/pkg-config +----------- +Called: `/usr/bin/pkg-config --cflags python-3.10` -> 0 +stdout: +-I/home/wshiah/code/miniconda3/envs/pyPDAF_294797_env/include/python3.10 +----------- +env[PKG_CONFIG_ALLOW_SYSTEM_LIBS]: 1 +env[PKG_CONFIG_PATH]: /home/wshiah/code/miniconda3/envs/pyPDAF_294797_env/lib/pkgconfig +env[PKG_CONFIG]: /usr/bin/pkg-config +----------- +Called: `/usr/bin/pkg-config --libs python-3.10` -> 0 +env[PKG_CONFIG_PATH]: /home/wshiah/code/miniconda3/envs/pyPDAF_294797_env/lib/pkgconfig +env[PKG_CONFIG]: /usr/bin/pkg-config +----------- +Called: `/usr/bin/pkg-config --libs python-3.10` -> 0 +Run-time dependency python found: YES 3.10 +Running compile: +Working directory: /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmpic6eo8o1 +Code: +program test + use iso_c_binding + + type(c_ptr) :: x + print '(i0)', c_sizeof(x) + end program test + +----------- +Command line: `gfortran /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmpic6eo8o1/testfile.f90 -o /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmpic6eo8o1/output.exe -D_FILE_OFFSET_BITS=64 -O0` -> 0 +Program stdout: + +8 + +Program stderr: + + +Running compile: +Working directory: /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmphe18afkr +Code: + +----------- +Command line: `gfortran /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmphe18afkr/testfile.f90 -o /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmphe18afkr/output.obj -D_FILE_OFFSET_BITS=64 -c -O0 --print-search-dirs` -> 0 +stdout: +install: /usr/lib/gcc/x86_64-linux-gnu/11/ +programs: =/usr/lib/gcc/x86_64-linux-gnu/11/:/usr/lib/gcc/x86_64-linux-gnu/11/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/11/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/bin/x86_64-linux-gnu/11/:/usr/lib/gcc/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/bin/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/bin/ +libraries: =/usr/lib/gcc/x86_64-linux-gnu/11/:/usr/lib/gcc/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/11/:/usr/lib/gcc/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/11/:/usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/11/../../../../lib/:/lib/x86_64-linux-gnu/11/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/11/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/lib/:/usr/lib/gcc/x86_64-linux-gnu/11/../../../:/lib/:/usr/lib/ +----------- +Running compile: +Working directory: /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmp8b3tcq_b +Code: +stop; end program +----------- +Command line: `gfortran /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmp8b3tcq_b/testfile.f90 -o /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmp8b3tcq_b/output.exe -D_FILE_OFFSET_BITS=64 -O0 /usr/lib/x86_64-linux-gnu/libblas.so -Wl,--allow-shlib-undefined` -> 0 +Library blas found: YES +Running compile: +Working directory: /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmpmo4yn5qg +Code: +stop; end program +----------- +Command line: `gfortran /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmpmo4yn5qg/testfile.f90 -o /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmpmo4yn5qg/output.exe -D_FILE_OFFSET_BITS=64 -O0 /usr/lib/x86_64-linux-gnu/liblapack.so -Wl,--allow-shlib-undefined` -> 0 +Library lapack found: YES +Running compile: +Working directory: /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmp3nqb6j5j +Code: +extern int i; +int i; + +----------- +Command line: `cc /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmp3nqb6j5j/testfile.c -o /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmp3nqb6j5j/output.obj -c -D_FILE_OFFSET_BITS=64 -O0 /O2` -> 1 +stderr: +cc: warning: /O2: linker input file unused because linking not done +cc: error: /O2: linker input file not found: No such file or directory +----------- +Compiler for C supports arguments /O2: NO +WARNING: Compiler for C does not support "/O2" +Running compile: +Working directory: /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmph2ojziwd +Code: +extern int i; +int i; + +----------- +Command line: `cc /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmph2ojziwd/testfile.c -o /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmph2ojziwd/output.obj -c -D_FILE_OFFSET_BITS=64 -O0 /GL` -> 1 +stderr: +cc: warning: /GL: linker input file unused because linking not done +cc: error: /GL: linker input file not found: No such file or directory +----------- +Compiler for C supports arguments /GL: NO +WARNING: Compiler for C does not support "/GL" +Running compile: +Working directory: /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmpk6ys51bk +Code: +extern int i; +int i; + +----------- +Command line: `cc /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmpk6ys51bk/testfile.c -o /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmpk6ys51bk/output.obj -c -D_FILE_OFFSET_BITS=64 -O0 -O3` -> 0 +Compiler for C supports arguments -O3: YES +Running compile: +Working directory: /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmpnnh7ir7t +Code: +stop; end program +----------- +Command line: `gfortran /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmpnnh7ir7t/testfile.f90 -o /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmpnnh7ir7t/output.obj -D_FILE_OFFSET_BITS=64 -c -O0 -O3` -> 0 +Compiler for Fortran supports arguments -O3: YES +Running compile: +Working directory: /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmpjqfzue8b +Code: +stop; end program +----------- +Command line: `gfortran /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmpjqfzue8b/testfile.f90 -o /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmpjqfzue8b/output.obj -D_FILE_OFFSET_BITS=64 -c -O0 -fdefault-real-8` -> 0 +Compiler for Fortran supports arguments -fdefault-real-8: YES +Running compile: +Working directory: /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmprajkiv58 +Code: +stop; end program +----------- +Command line: `gfortran /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmprajkiv58/testfile.f90 -o /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmprajkiv58/output.obj -D_FILE_OFFSET_BITS=64 -c -O0 -DUSE_PDAF` -> 0 +Compiler for Fortran supports arguments -DUSE_PDAF: YES +Using cached compile: +Cached command line: gfortran /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmpnnh7ir7t/testfile.f90 -o /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-private/tmpnnh7ir7t/output.obj -D_FILE_OFFSET_BITS=64 -c -O0 -O3 + +Code: + stop; end program +Cached compiler stdout: + +Cached compiler stderr: + +Compiler for Fortran supports arguments -O3: YES (cached) +Running command: /home/wshiah/code/miniconda3/envs/pyPDAF_294797_env/bin/python3.10 -c 'import os; os.chdir(".."); import numpy; print(numpy.get_include())' +--- stdout --- +/ssddata/shiweijie/tmp/pip-build-env-ygthrxi6/overlay/lib/python3.10/site-packages/numpy/_core/include + +--- stderr --- + + + +../../meson.build:88:18: ERROR: File PDAF/src/PDAF3_init.F90 does not exist. diff --git a/pyPDAF/source/build/cp310/meson-logs/meson-setup.txt b/pyPDAF/source/build/cp310/meson-logs/meson-setup.txt new file mode 100644 index 0000000000000000000000000000000000000000..47e88c1378a3112fc9b8383c8ad84db860c0c2c3 --- /dev/null +++ b/pyPDAF/source/build/cp310/meson-logs/meson-setup.txt @@ -0,0 +1,32 @@ +The Meson build system +Version: 1.10.0 +Source dir: /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source +Build dir: /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310 +Build type: native build +Project name: pyPDAF +Project version: 1.0.4 +Fortran compiler for the host machine: gfortran (gcc 11.4.0 "GNU Fortran (Ubuntu 11.4.0-1ubuntu1~22.04.2) 11.4.0") +Fortran linker for the host machine: gfortran ld.bfd 2.38 +C compiler for the host machine: /usr/bin/ccache cc (gcc 12.3.0 "cc (Ubuntu 12.3.0-1ubuntu1~22.04.2) 12.3.0") +C linker for the host machine: cc ld.bfd 2.38 +Cython compiler for the host machine: cython (cython 3.2.2) +Host machine cpu family: x86_64 +Host machine cpu: x86_64 +Program python found: YES (/home/wshiah/code/miniconda3/envs/pyPDAF_294797_env/bin/python3.10) +Found pkg-config: YES (/usr/bin/pkg-config) 0.29.2 +Run-time dependency python found: YES 3.10 +Library blas found: YES +Library lapack found: YES +Compiler for C supports arguments /O2: NO +WARNING: Compiler for C does not support "/O2" +Compiler for C supports arguments /GL: NO +WARNING: Compiler for C does not support "/GL" +Compiler for C supports arguments -O3: YES +Compiler for Fortran supports arguments -O3: YES +Compiler for Fortran supports arguments -fdefault-real-8: YES +Compiler for Fortran supports arguments -DUSE_PDAF: YES +Compiler for Fortran supports arguments -O3: YES (cached) + +../../meson.build:88:18: ERROR: File PDAF/src/PDAF3_init.F90 does not exist. + +A full log can be found at /export/project/shiweijie/ghh/LLM_MCP_RAG/MCP-agent-github-repo-output/workspace/pyPDAF/source/build/cp310/meson-logs/meson-log.txt diff --git a/pyPDAF/source/build/cp310/meson-private/meson.lock b/pyPDAF/source/build/cp310/meson-private/meson.lock new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/pyPDAF/source/build/cp310/meson-private/sanitycheckc.c b/pyPDAF/source/build/cp310/meson-private/sanitycheckc.c new file mode 100644 index 0000000000000000000000000000000000000000..a27020ebda7c75c70af41b7c8844e3a516a3df69 --- /dev/null +++ b/pyPDAF/source/build/cp310/meson-private/sanitycheckc.c @@ -0,0 +1 @@ +int main(void) { int class=0; return class; } diff --git a/pyPDAF/source/build/cp310/meson-private/sanitycheckc.exe b/pyPDAF/source/build/cp310/meson-private/sanitycheckc.exe new file mode 100644 index 0000000000000000000000000000000000000000..d5db80562fb27618f33aee3a4623e4243c311334 Binary files /dev/null and b/pyPDAF/source/build/cp310/meson-private/sanitycheckc.exe differ diff --git a/pyPDAF/source/build/cp310/meson-private/sanitycheckf.exe b/pyPDAF/source/build/cp310/meson-private/sanitycheckf.exe new file mode 100644 index 0000000000000000000000000000000000000000..b3929fda95b688f958e31197d6b6bc4d8488d110 Binary files /dev/null and b/pyPDAF/source/build/cp310/meson-private/sanitycheckf.exe differ diff --git a/pyPDAF/source/build/cp310/meson-private/sanitycheckf.f b/pyPDAF/source/build/cp310/meson-private/sanitycheckf.f new file mode 100644 index 0000000000000000000000000000000000000000..e44b1f5a3355b3cafe0cac607cbd8410b730cca0 --- /dev/null +++ b/pyPDAF/source/build/cp310/meson-private/sanitycheckf.f @@ -0,0 +1,3 @@ + PROGRAM MAIN + PRINT *, "Fortran compilation is working." + END diff --git a/pyPDAF/source/build/cp310/meson-python-native-file.ini b/pyPDAF/source/build/cp310/meson-python-native-file.ini new file mode 100644 index 0000000000000000000000000000000000000000..577cac4e11e93eb8cda6290ad3f8e0e79f42befe --- /dev/null +++ b/pyPDAF/source/build/cp310/meson-python-native-file.ini @@ -0,0 +1,3 @@ + +[binaries] +python = '/home/wshiah/code/miniconda3/envs/pyPDAF_294797_env/bin/python3.10' diff --git a/pyPDAF/source/conda.recipe/bld.bat b/pyPDAF/source/conda.recipe/bld.bat new file mode 100644 index 0000000000000000000000000000000000000000..bdf49d200ec9818d4bbccc8c08ea5b72f65054dd --- /dev/null +++ b/pyPDAF/source/conda.recipe/bld.bat @@ -0,0 +1,14 @@ +@echo on + +set CXX=clang-cl +set CC=clang-cl +set FC=flang-new +set MSMPI_INC=%LIBRARY_INC% +set MSMPI_LIB64=%LIBRARY_LIB% + +"%PYTHON%" -m pip install . -v --no-build-isolation^ + -Cbuild-dir=build --config-settings=setup-args="-Dblas_lib=openblas"^ + --config-settings=setup-args="-Dincdirs="%LIBRARY_INC%^ + --config-settings=setup-args="-Dlibdirs="%LIBRARY_LIB%^ + --config-settings=setup-args="-Dmpi_mod="%LIBRARY_INC%"\mpi.f90"^ + --config-settings=setup-args="-Dbuildtype=release" \ No newline at end of file diff --git a/pyPDAF/source/conda.recipe/build.sh b/pyPDAF/source/conda.recipe/build.sh new file mode 100644 index 0000000000000000000000000000000000000000..97ac062a6bfdd014817ac7c5522c7852669af6fa --- /dev/null +++ b/pyPDAF/source/conda.recipe/build.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -ex + +CC=mpicc +FC=mpifort + +$PYTHON -m pip install . -v --no-build-isolation \ + --config-settings=setup-args="-Dblas_lib=['openblas',]" \ + --config-settings=setup-args="-Dincdirs="$PREFIX"/include" \ + --config-settings=setup-args="-Dlibdirs="$PREFIX"/lib" \ + --config-settings=setup-args="-Dbuildtype=release" \ No newline at end of file diff --git a/pyPDAF/source/conda.recipe/conda_build_config.yaml b/pyPDAF/source/conda.recipe/conda_build_config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..50829dfaa9bd68ceae02db0c2491422f4e71d6ab --- /dev/null +++ b/pyPDAF/source/conda.recipe/conda_build_config.yaml @@ -0,0 +1,31 @@ +python: + - 3.11 + - 3.12 + - 3.13 + +c_compiler_version: + - 14 # [linux] + +# there seems to be bug in gfortran 15.1.0 +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119928 +# therefore, we pin gfortran 14 +fortran_compiler_version: + - 14 # [not win] + +c_compiler: + - clang # [win] + +fortran_compiler: + - flang # [win] + +numpy_version: + - '>2' + +mpi: + - mpich # [not win] + - msmpi # [win] + +# meson-python 0.18 cannot be installed on Windows +pymeson: + - <0.18 # [win] + - '>=0.18' # [not win] diff --git a/pyPDAF/source/conda.recipe/meta.yaml b/pyPDAF/source/conda.recipe/meta.yaml new file mode 100644 index 0000000000000000000000000000000000000000..26632d07201272b3eac875d7fb8e67ac004a5096 --- /dev/null +++ b/pyPDAF/source/conda.recipe/meta.yaml @@ -0,0 +1,49 @@ +{% set version = "1.0.4" %} + +package: + name: pypdaf + version: {{ version }} + +source: + path: .. + +build: + number: 0 + +requirements: + host: + - python + - meson-python {{ pymeson }} + - numpy {{numpy_version}} + - mpi=*={{ mpi }} + - mpi4py + - blas=*=openblas + - flang-rt_win-64 # [win] + - libflang # [win] + build: + - python + - {{ compiler('c') }} + - {{ compiler('fortran') }} + - vs2022_win-64 # [win] + - numpy {{numpy_version}} + - cython + run: + - flang-rt_win-64 # [win] + - python + - numpy + - mpi=*={{ mpi }} + - mpi4py + - blas=*=openblas + +pin_run_as_build: + mpi: x.x + mpi4py: x.x + blas: x.x + +about: + home: https://github.com/yumengch/pyPDAF + summary: A Python interface to PDAF + description: pyPDAF is a python interface to the Fortran-based PDAF library + license: GPL + doc_url: https://yumengch.github.io/pyPDAF/index.html + dev_url: https://github.com/yumengch/pyPDAF \ No newline at end of file diff --git a/pyPDAF/source/docs/Makefile b/pyPDAF/source/docs/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..be50b8ac8947c6f1784819382d7c5dda6296e1c5 --- /dev/null +++ b/pyPDAF/source/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= -v +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/pyPDAF/source/docs/make.bat b/pyPDAF/source/docs/make.bat new file mode 100644 index 0000000000000000000000000000000000000000..6fcf05b4b76f8b9774c317ac8ada402f8a7087de --- /dev/null +++ b/pyPDAF/source/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/pyPDAF/source/docs/source/API.rst b/pyPDAF/source/docs/source/API.rst new file mode 100644 index 0000000000000000000000000000000000000000..8f20b85809aed3a2109968b8625d0942eeefe69a --- /dev/null +++ b/pyPDAF/source/docs/source/API.rst @@ -0,0 +1,306 @@ +API +=== + +This page provides a list of pyPDAF functions that are intended for users. +They are grouped by functionalities. Clicking on a function name will lead to +its documentation page. + +These are not all available functions in pyPDAF. Similar to PDAF, pyPDAF maintains +backward compatible legacy functions used prior to PDAF 3.0. +For a complete list of functions, +please refer to the [hidden and legacy function page](hidden_functions.md) + +.. contents:: + :local: + :depth: 2 + +Initialisation and finalisation +------------------------------- +.. autosummary:: + :toctree: _autosummary + :recursive: + + pyPDAF.init + pyPDAF.set_parallel + pyPDAF.init_forecast + pyPDAF.PDAFomi.init + pyPDAF.PDAFomi.init_local + pyPDAF.deallocate + +DA algorithms +------------------------------ + +Sequential DA +^^^^^^^^^^^^^ + +diagnoal observation matrix +""""""""""""""""""""""""""" +.. autosummary:: + :toctree: _autosummary + :recursive: + + pyPDAF.assimilate + pyPDAF.assim_offline + +non-diagnoal observation matrix +""""""""""""""""""""""""""""""" +.. autosummary:: + :toctree: _autosummary + :recursive: + + pyPDAF.assimilate_local_nondiagr + pyPDAF.assimilate_global_nondiagr + pyPDAF.assimilate_lnetf_nondiagr + pyPDAF.assimilate_lknetf_nondiagr + pyPDAF.assimilate_enkf_nondiagr + pyPDAF.assimilate_nonlin_nondiagr + + pyPDAF.assim_offline_local_nondiagr + pyPDAF.assim_offline_global_nondiagr + pyPDAF.assim_offline_lnetf_nondiagr + pyPDAF.assim_offline_lknetf_nondiagr + pyPDAF.assim_offline_enkf_nondiagr + pyPDAF.assim_offline_lenkf_nondiagr + pyPDAF.assim_offline_nonlin_nondiagr + +Variational DA +^^^^^^^^^^^^^^ + +diagnoal observation matrix +""""""""""""""""""""""""""" +.. autosummary:: + :toctree: _autosummary + :recursive: + + pyPDAF.assimilate_3dvar_all + pyPDAF.assim_offline_3dvar_all + +non-diagnoal observation matrix +""""""""""""""""""""""""""""""" +.. autosummary:: + :toctree: _autosummary + :recursive: + + pyPDAF.assimilate_3dvar_nondiagr + pyPDAF.assimilate_en3dvar_estkf_nondiagr + pyPDAF.assimilate_en3dvar_lestkf_nondiagr + pyPDAF.assimilate_hyb3dvar_estkf_nondiagr + pyPDAF.assimilate_hyb3dvar_lestkf_nondiagr + + pyPDAF.assim_offline_3dvar_nondiagr + pyPDAF.assim_offline_en3dvar_estkf_nondiagr + pyPDAF.assim_offline_en3dvar_lestkf_nondiagr + pyPDAF.assim_offline_hyb3dvar_estkf_nondiagr + pyPDAF.assim_offline_hyb3dvar_lestkf_nondiagr + + +OMI functions +------------- + +setter functions +^^^^^^^^^^^^^^^^^^^^^^ +.. autosummary:: + :toctree: _autosummary + :recursive: + + pyPDAF.PDAFomi.set_doassim + pyPDAF.PDAFomi.set_disttype + pyPDAF.PDAFomi.set_ncoord + pyPDAF.PDAFomi.set_obs_err_type + pyPDAF.PDAFomi.set_use_global_obs + pyPDAF.PDAFomi.set_inno_omit + pyPDAF.PDAFomi.set_inno_omit_ivar + pyPDAF.PDAFomi.set_id_obs_p + pyPDAF.PDAFomi.set_icoeff_p + pyPDAF.PDAFomi.set_domainsize + pyPDAF.PDAFomi.set_name + pyPDAF.PDAFomi.gather_obs + + +Observation operators +^^^^^^^^^^^^^^^^^^^^^ +.. autosummary:: + :toctree: _autosummary + :recursive: + + pyPDAF.PDAFomi.obs_op_gridpoint + pyPDAF.PDAFomi.obs_op_gridavg + pyPDAF.PDAFomi.obs_op_extern + pyPDAF.PDAFomi.obs_op_interp_lin + pyPDAF.PDAFomi.obs_op_adj_gridavg + pyPDAF.PDAFomi.obs_op_adj_gridpoint + pyPDAF.PDAFomi.obs_op_adj_interp_lin + pyPDAF.PDAFomi.gather_obsstate + +Interpolations +^^^^^^^^^^^^^^ +.. autosummary:: + :toctree: _autosummary + :recursive: + + pyPDAF.PDAFomi.get_interp_coeff_tri + pyPDAF.PDAFomi.get_interp_coeff_lin1d + pyPDAF.PDAFomi.get_interp_coeff_lin + +Localisation +^^^^^^^^^^^^ +.. autosummary:: + :toctree: _autosummary + :recursive: + + pyPDAF.PDAFomi.init_dim_obs_l_iso + pyPDAF.PDAFomi.init_dim_obs_l_noniso + pyPDAF.PDAFomi.init_dim_obs_l_noniso_locweights + pyPDAF.PDAFomi.observation_localization_weights + pyPDAF.PDAFomi.set_domain_limits + pyPDAF.PDAFomi.get_domain_limits_unstr + pyPDAF.PDAFomi.set_localize_covar_iso + pyPDAF.PDAFomi.set_localize_covar_noniso + pyPDAF.PDAFomi.set_localize_covar_noniso_locweights + +Custom local observation initialisation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. autosummary:: + :toctree: _autosummary + :recursive: + + pyPDAF.PDAFomi.set_localization + pyPDAF.PDAFomi.set_localization_noniso + pyPDAF.PDAFomi.set_dim_obs_l + pyPDAF.PDAFomi.store_obs_l_index + pyPDAF.PDAFomi.store_obs_l_index_vdist + +Diagnostics +^^^^^^^^^^^ +.. autosummary:: + :toctree: _autosummary + :recursive: + + pyPDAF.PDAFomi.check_error + pyPDAF.PDAFomi.set_debug_flag + pyPDAF.PDAFomi.set_obs_diag + pyPDAF.PDAFomi.diag_dimobs + pyPDAF.PDAFomi.diag_get_hx + pyPDAF.PDAFomi.diag_get_hxmean + pyPDAF.PDAFomi.diag_get_ivar + pyPDAF.PDAFomi.diag_get_obs + pyPDAF.PDAFomi.diag_nobstypes + pyPDAF.PDAFomi.diag_obs_rmsd + pyPDAF.PDAFomi.diag_stats + + +Localisation functions +---------------------- +.. autosummary:: + :toctree: _autosummary + :recursive: + + pyPDAF.PDAFlocal.set_indices + pyPDAF.PDAFlocal.set_increment_weights + pyPDAF.PDAFlocal.clear_increment_weights + pyPDAF.PDAF.correlation_function + pyPDAF.PDAF.local_weight + pyPDAF.PDAF.local_weights + +Utilities +--------- + +PDAF state and setup information +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. autosummary:: + :toctree: _autosummary + :recursive: + + pyPDAF.get_fcst_info + pyPDAF.PDAF.get_assim_flag + pyPDAF.PDAF.get_localfilter + pyPDAF.PDAF.get_local_type + pyPDAF.PDAF.get_memberid + pyPDAF.PDAF.get_obsmemberid + pyPDAF.PDAF.get_smoother_ens + pyPDAF.PDAF.print_filter_types + pyPDAF.PDAF.print_da_types + pyPDAF.PDAF.print_info + + +Observation MPI handling +^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. autosummary:: + :toctree: _autosummary + :recursive: + + pyPDAF.PDAF.gather_dim_obs_f + pyPDAF.PDAF.gather_obs_f + pyPDAF.PDAF.gather_obs_f2 + pyPDAF.PDAF.gather_obs_f_flex + pyPDAF.PDAF.gather_obs_f2_flex + + +Synthetic experiments +^^^^^^^^^^^^^^^^^^^^^ +.. autosummary:: + :toctree: _autosummary + :recursive: + + pyPDAF.generate_obs + pyPDAF.generate_obs_offline + + +Incremental analysis update +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. autosummary:: + :toctree: _autosummary + :recursive: + + pyPDAF.PDAF.iau_init + pyPDAF.PDAF.iau_reset + pyPDAF.PDAF.iau_set_pointer + +Statistical diagnostics +^^^^^^^^^^^^^^^^^^^^^^^ +.. autosummary:: + :toctree: _autosummary + :recursive: + + pyPDAF.PDAF.diag_effsample + pyPDAF.PDAF.diag_ensstats + pyPDAF.PDAF.diag_histogram + pyPDAF.PDAF.diag_crps_mpi + pyPDAF.PDAF.diag_crps_nompi + +Ensemble generation +^^^^^^^^^^^^^^^^^^^ +.. autosummary:: + :toctree: _autosummary + :recursive: + + pyPDAF.PDAF.eofcovar + pyPDAF.PDAF.sample_ens + +PDAF debug options +^^^^^^^^^^^^^^^^^^^ +.. autosummary:: + :toctree: _autosummary + :recursive: + + pyPDAF.PDAF.set_debug_flag + +Advanced manipulation +^^^^^^^^^^^^^^^^^^^^^ +.. autosummary:: + :toctree: _autosummary + :recursive: + + pyPDAF.PDAF.set_iparam + pyPDAF.PDAF.set_rparam + pyPDAF.PDAF.set_comm_pdaf + + pyPDAF.PDAF.set_ens_pointer + pyPDAF.PDAF.set_memberid + pyPDAF.PDAF.set_offline_mode + pyPDAF.PDAF.set_seedset + pyPDAF.PDAF.set_smoother_ens + + pyPDAF.PDAF.force_analysis + pyPDAF.PDAF.reset_forget + diff --git a/pyPDAF/source/docs/source/conf.py b/pyPDAF/source/docs/source/conf.py new file mode 100644 index 0000000000000000000000000000000000000000..e55da740870a3e4837a96d02073282593fb0a0df --- /dev/null +++ b/pyPDAF/source/docs/source/conf.py @@ -0,0 +1,71 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + + +# -- Project information ----------------------------------------------------- + +project = 'pyPDAF' +copyright = '2025 University of Reading and National Centre for Earth Observation' +author = 'Yumeng Chen, Lars Nerger' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.autosummary', + 'sphinx.ext.mathjax', + 'sphinx.ext.coverage', 'sphinx.ext.napoleon', 'myst_parser' + ] + +autosummary_generate = True + +autoclass_content = 'both' + +napoleon_google_docstring = False +napoleon_numpy_docstring = True +napoleon_include_init_with_doc = True +napoleon_include_private_with_doc = True +napoleon_include_special_with_doc = True +napoleon_use_admonition_for_examples = False +napoleon_use_admonition_for_notes = False +napoleon_use_admonition_for_references = False +napoleon_use_ivar = False +napoleon_use_param = True +napoleon_use_rtype = True +napoleon_preprocess_types = False +napoleon_type_aliases = None +napoleon_attr_annotations = True + +myst_heading_anchors = 3 + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + +source_suffix = {'.rst': 'restructuredtext', '.md': 'markdown'} +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' +html_theme_options = { + "description": "A Python interface to Parallel Data Assimilation Framework.", + "github_button": True, + "github_user": "yumengch", + "github_repo": "pyPDAF", + "body_max_width": "none" +} +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] diff --git a/pyPDAF/source/docs/source/develop.md b/pyPDAF/source/docs/source/develop.md new file mode 100644 index 0000000000000000000000000000000000000000..af67e67b209751f62dfc584363b73bc1211a5322 --- /dev/null +++ b/pyPDAF/source/docs/source/develop.md @@ -0,0 +1,327 @@ +# Developer Guide + +The following guide explains the structure, implementation details, and mechanisms +used in `pyPDAF`. This guide is aimed at developers who wish to understand the +existing framework, make modifications, or contribute to its development. + +--- + +## Overview + +`pyPDAF` bridges Python and Fortran by leveraging the `Cython` library. +As Python is implemented in C, any interaction between Python and Fortran is +effectively handled as C-to-Fortran communication. + +`Cython` automatically converts its module to `C` source code. The interoperability +with `Fortran` is achieved by the Fortran 2003 feature `iso_c_binding` module. + +Contributions to the library can include raising issues, suggesting features, +or submitting pull requests with code enhancements. + +--- + +## Adding a new Fortran function in pyPDAF + +### Fortran Subroutines and Wrappers +The Fortran subroutine wrappers that are interoperable with C functions are +given in [src/fortran](https://github.com/yumengch/pyPDAF/tree/main/src/fortran). + +#### Interoperability with `bind(c)` +Fortran subroutines use the `bind(c)` keyword for compatibility with C. + +Since PDAF does not use this keyword, `pyPDAF` provides its own wrapper subroutines that: +1. Subroutine names begin with the prefix `c__` to denote compatibility. +2. Arguments use corresponding C types. +3. User-supplied functions must be declared with [specified interface](https://github.com/yumengch/pyPDAF/tree/main/src/fortran/pdaf_c_cb_interface.f90) +4. Bind(c) user-supplied functions must be converted to Fortran subroutines by + pointers and wrapper subroutines in [src/fortran/pdaf_c_f_interface.f90](https://github.com/yumengch/pyPDAF/tree/main/src/fortran/pdaf_c_f_interface.f90). + This is a requirement in `flang`. +5. We do not use features that interoperable with derived types. This is because + current standard does not support allocatable arrays in derived types. + Therefore, `obs_f` and `obs_l` in PDAFomi are allocated in Fortran referenced + by indices, and getting and setter functions. + +#### Example Wrapper Subroutine +```fortran +subroutine c__PDAFomi_set_doassim(i_obs, doassim) bind(c) + ! Index of observation types + integer(c_int), intent(in) :: i_obs + ! Flag to determine assimilation (0: no, 1: yes) + integer(c_int), intent(in) :: doassim + thisobs(i_obs)%doassim = doassim +end subroutine c__PDAFomi_set_doassim +``` + +--- + +### Cython Integration + +#### Cython Declarations +To call Fortran subroutines in Python, `pyPDAF` uses Cython declarations +defined in `.pxd` files (e.g., `src/pyPDAF/PDAF.pxd`). Example: +```cython +cdef extern void c__pdaf_eofcovar ( + int* dim_state, int* nstates, int* nfields, int* dim_fields, + int* offsets, int* remove_mstate, int* do_mv, double* states, + double* stddev, double* svals, double* svec, double* meanstate, + int* verbose, int* status) noexcept; +``` + +#### Python Wrappers +These Cython declarations are wrapped into Python functions to make them +accessible to users. Wrappers should return all `intent(out)` or `intent(inout)` +arguments in Python-friendly structures. + +Example: +```cython +def eofcovar(int dim, int nstates, int nfields, int [::1] dim_fields, + int [::1] offsets, int remove_mstate, int do_mv, + double [::1,:] states, double [::1] meanstate, int verbose): + """ + EOF analysis of an ensemble of state vectors by singular value decomposition. + + Typically, this function is used with :func:`pyPDAF.PDAF.SampleEns` + to generate an ensemble of a chosen size (up to the number of EOFs plus one). + + Here, the function performs a singular value decomposition + of the ensemble anomaly of the input matrix, + which is usually an ensemble formed by state vectors + at multiple time steps. + The singular values and corresponding singular vectors + can be used to construct a covariance matrix. + This can be used as the initial error covariance for the initial ensemble. + + A multivariate scaling can be performed to ensure that all fields + in the state vectors have unit variance. + + It can be useful to store more EOFs than one finally + might want to use to have the flexibility + to carry the ensemble size. + + + See Also + -------- + `PDAF webpage `_ + + Parameters + ---------- + dim : int + Dimension of state vector + nstates : int + Number of state vectors + nfields : int + Number of fields in state vector + dim_fields : ndarray[np.intc, ndim=1] + Size of each field + Array shape: (nfields) + offsets : ndarray[np.intc, ndim=1] + Start position of each field + Array shape: (nfields) + remove_mstate : int + 1: subtract mean state from states + do_mv : int + 1: Do multivariate scaling; 0: no scaling + states : ndarray[np.float64, ndim=2] + State perturbations + Array shape: (dim, nstates) + meanstate : ndarray[np.float64, ndim=1] + Mean state (only changed if remove_mstate=1) + Array shape: (dim) + verbose : int + Verbosity flag + + Returns + ------- + states : ndarray[np.float64, ndim=2] + State perturbations + Array shape: (dim, nstates) + stddev : ndarray[np.float64, ndim=1] + Standard deviation of field variability + Array shape: (nfields) + svals : ndarray[np.float64, ndim=1] + Singular values divided by sqrt(nstates-1) + Array shape: (nstates) + svec : ndarray[np.float64, ndim=2] + Singular vectors + Array shape: (dim, nstates) + meanstate : ndarray[np.float64, ndim=1] + Mean state (only changed if remove_mstate=1) + Array shape: (dim) + status : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] states_np = np.asarray(states, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] stddev_np = np.zeros((nfields), dtype=np.float64, order="F") + cdef double [::1] stddev = stddev_np + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] svals_np = np.zeros((nstates), dtype=np.float64, order="F") + cdef double [::1] svals = svals_np + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] svec_np = np.zeros((dim, nstates), dtype=np.float64, order="F") + cdef double [::1,:] svec = svec_np + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] meanstate_np = np.asarray(meanstate, dtype=np.float64, order="F") + cdef int status + with nogil: + c__pdaf_eofcovar(&dim, &nstates, &nfields, &dim_fields[0], + &offsets[0], &remove_mstate, &do_mv, &states[0,0], + &stddev[0], &svals[0], &svec[0,0], &meanstate[0], + &verbose, &status) + + return states_np, stddev_np, svals_np, svec_np, meanstate_np, status +``` + +--- + +#### Handling Callback Functions + +Callback functions allow users to provide information for data assimilation. +However, Fortran expects these routines to follow specific interfaces. +These are handled in `src/pyPDAF/pdaf_c_cb_interface.pxd` and corresponding +`src/pyPDAF/pdaf_c_cb_interface.pyx`. + +Example: +```cython +cdef void c__init_ens_pdaf(int* filtertype, int* dim_p, int* dim_ens, + double* state_p, double* uinv, double* ens_p, int* flag) noexcept with gil: + """Fill the ensemble array that is provided by PDAF with an initial ensemble of model states. + + This function is called by :func:`pyPDAF.PDAF.init`. The initialised + ensemble array will be distributed to model by :func:`pyPDAF.PDAF.init_forecast`. + + Parameters + ---------- + filtertype : int + filter type given in PDAF_init + dim_p : int + PE-local state dimension given by PDAF_init + dim_ens : int + number of ensemble members + state_p : ndarray[np.float64, ndim=1] + PE-local model state + This array must be filled with the initial + state of the model for SEEK, but it is not + used for ensemble-based filters. + One can still make use of this array within + this function. + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + This array is the inverse of matrix + formed by right singular vectors of error + covariance matrix of ensemble perturbations. + This array has to be filled in SEEK, but it is + not used for ensemble-based filters. + Nevertheless, one can still make use of this + array within this function e.g., + for generating an initial ensemble perturbation + from a given covariance matrix. + Dimension of this array is determined by the + filter type. + * (dim_ens, dim_ens) for (L)ETKF, (L)NETF, (L)KNETF, and SEEK + * (dim_ens - 1, dim_ens - 1) for (L)SEIK, (L)ESTKF, and 3DVar using ensemble + * (1, 1) for (L)EnKF, particle filters and gen_obs + Array shape: (dim_ens - 1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + This array must be filled with the initial + state of the model for SEEK, but it is not + used for ensemble-based filters. + One can still make use of this array within + this function. + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + This array is the inverse of matrix + formed by right singular vectors of error + covariance matrix of ensemble perturbations. + This array has to be filled in SEEK, but it is + not used for ensemble-based filters. + Nevertheless, one can still make use of this + array within this function e.g., + for generating an initial ensemble perturbation + from a given covariance matrix. + Dimension of this array is determined by the + filter type. + * (dim_ens, dim_ens) for (L)ETKF, (L)NETF, (L)KNETF, and SEEK + * (dim_ens - 1, dim_ens - 1) for (L)SEIK, (L)ESTKF, and 3DVar using ensemble + * (1, 1) for (L)EnKF, particle filters and gen_obs + Array shape: (dim_ens - 1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + """ + cdef size_t uinv_len = max(dim_ens[0]-1, 1) + cdef double[::1] state_p_np = np.asarray( state_p, order="F") + cdef double[::1,:] uinv_np = np.asarray( uinv, order="F") + cdef double[::1,:] ens_p_np = np.asarray( ens_p, order="F") + + state_p_np,uinv_np,ens_p_np,flag[0] = (init_ens_pdaf)( + filtertype[0], + dim_p[0], + dim_ens[0], + state_p_np.base, + uinv_np.base, + ens_p_np.base, + flag[0]) + + cdef double[::1] state_p_new + if state_p != &state_p_np[0]: + state_p_new = np.asarray( state_p, order="F") + state_p_new[...] = state_p_np + warnings.warn("The memory address of state_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + cdef double[::1,:] uinv_new + if uinv != &uinv_np[0,0]: + uinv_new = np.asarray( uinv, order="F") + uinv_new[...] = uinv_np + warnings.warn("The memory address of uinv is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + cdef double[::1,:] ens_p_new + if ens_p != &ens_p_np[0,0]: + ens_p_new = np.asarray( ens_p, order="F") + ens_p_new[...] = ens_p_np + warnings.warn("The memory address of ens_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) +``` +where `init_ens_pdaf` is defined in `src/pyPDAF/pdaf_c_cb_interface.pxd` as a pointer: +`cdef void* init_ens_pdaf = NULL;`. +The pointer is associated in pyPDAF functions, for example, in `src/pyPDAF/PDAF3/_pdaf3_c.pyx`: +```cython +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +pdaf_cb.init_ens_pdaf = py__init_ens_pdaf +``` +where `py__init_ens_pdaf` is the Python call-back function. The C function, +`pdaf_cb.c__init_ens_pdaf`, is +used for calling Fortran subroutines: +```cython + with nogil: + c__pdaf3_init(&filtertype, &subtype, &stepnull, ¶m_int[0], + &dim_pint, ¶m_real[0], &dim_preal, + pdaf_cb.c__init_ens_pdaf, &in_screen, &outflag) +``` + +#### Caveats +1. **Pass-by-Reference in Fortran:** Fortran passes arguments by reference, while Python’s behavior depends on the object type. +2. **Maintaining Consistency:** When Python functions modify arguments, ensure the original reference is preserved. + +Example Safety Check: +```python + cdef double[::1] state_p_new + if state_p != &state_p_np[0]: + state_p_new = np.asarray( state_p) + state_p_new[...] = state_p_np + warnings.warn("The memory address of state_p is changed in c__init_ens_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) +``` + +#### Exposing the function to pyPDAF and Mypy +To expose your function to pyPDAF or subpackages of pyPDAF, you need to import +it in `__init__.py` in corresponding directories. Further, as pyPDAF supports +type checking and other Python support features. You can add typing and docstring +to stub files ending with `.pyi`. diff --git a/pyPDAF/source/docs/source/figs/communicators_PDAFonline.png b/pyPDAF/source/docs/source/figs/communicators_PDAFonline.png new file mode 100644 index 0000000000000000000000000000000000000000..62b843d754f1bfdfbb2051557e3de7bdaa5729fd Binary files /dev/null and b/pyPDAF/source/docs/source/figs/communicators_PDAFonline.png differ diff --git a/pyPDAF/source/docs/source/hidden_functions.md b/pyPDAF/source/docs/source/hidden_functions.md new file mode 100644 index 0000000000000000000000000000000000000000..8382e8f9affa2d31ac47f4ba143bfedee35d23ea --- /dev/null +++ b/pyPDAF/source/docs/source/hidden_functions.md @@ -0,0 +1,749 @@ +# Legacy and internal PDAF functions + +This page gives all available functions in pyPDAF. They are accesible in the +submodules. Due to the amount of functions available, this documentation cannot +provide detailed explanations for each function. + +To use these functions, one has to import the individual module first. For example, +if one wants to use PDAF subroutine `PDAF_assimilate_3dvar` located in +`pyPDAF.PDAF.assim`, one can only use `pyPDAF.PDAF.assim.assimilate_3dvar` after +`import pyPDAF.PDAF.assim`. One cannot simply access these functions by `import pyPDAF` +like those functions given in [API](API.rst). + +However, the developers encourage the users to create new issues to request +information for specific function or functionalities so that the developers +can understand the needs from users. + +Explanations of certain legacy functions may be found in PDAF wiki page by the +corresponding PDAF subroutines. One can find the name of PDAF subroutines by +the pyPDAF subpackage name and function names. For example, +`pyPDAF.PDAF._pdaf_c.deallocate` calls `PDAF_deallocate` in PDAF. The module names +are typically irrelevant. This is similar for `PDAFomi` subroutines, e.g., +`PDAFomi_check_error` is `pyPDAF.PDAFomi._pdafomi_c.check_error`. + +One exception is for some `3dvar` functions. As numbers cannot be the first +letter of variable or function names, an additional `_` is added for some PDAF +internal functionss. + + +## pyPDAF.PDAF +### pyPDAF.PDAF._pdaf_c + - pyPDAF.PDAF._pdaf_c.correlation_function + - pyPDAF.PDAF._pdaf_c.deallocate + - pyPDAF.PDAF._pdaf_c.eofcovar + - pyPDAF.PDAF._pdaf_c.force_analysis + - pyPDAF.PDAF._pdaf_c.gather_dim_obs_f + - pyPDAF.PDAF._pdaf_c.gather_obs_f + - pyPDAF.PDAF._pdaf_c.gather_obs_f2 + - pyPDAF.PDAF._pdaf_c.gather_obs_f2_flex + - pyPDAF.PDAF._pdaf_c.gather_obs_f_flex + - pyPDAF.PDAF._pdaf_c.get_fcst_info + - pyPDAF.PDAF._pdaf_c.init + - pyPDAF.PDAF._pdaf_c.init_forecast + - pyPDAF.PDAF._pdaf_c.local_weight + - pyPDAF.PDAF._pdaf_c.local_weights + - pyPDAF.PDAF._pdaf_c.print_da_types + - pyPDAF.PDAF._pdaf_c.print_filter_types + - pyPDAF.PDAF._pdaf_c.print_info + - pyPDAF.PDAF._pdaf_c.reset_forget + - pyPDAF.PDAF._pdaf_c.sample_ens + +### pyPDAF.PDAF.assim + - pyPDAF.PDAF.assim.assim_offline_3dvar + - pyPDAF.PDAF.assim.assim_offline_en3dvar_estkf + - pyPDAF.PDAF.assim.assim_offline_en3dvar_lestkf + - pyPDAF.PDAF.assim.assim_offline_enkf + - pyPDAF.PDAF.assim.assim_offline_ensrf + - pyPDAF.PDAF.assim.assim_offline_estkf + - pyPDAF.PDAF.assim.assim_offline_etkf + - pyPDAF.PDAF.assim.assim_offline_hyb3dvar_estkf + - pyPDAF.PDAF.assim.assim_offline_hyb3dvar_lestkf + - pyPDAF.PDAF.assim.assim_offline_lenkf + - pyPDAF.PDAF.assim.assim_offline_lestkf + - pyPDAF.PDAF.assim.assim_offline_letkf + - pyPDAF.PDAF.assim.assim_offline_lknetf + - pyPDAF.PDAF.assim.assim_offline_lnetf + - pyPDAF.PDAF.assim.assim_offline_lseik + - pyPDAF.PDAF.assim.assim_offline_netf + - pyPDAF.PDAF.assim.assim_offline_pf + - pyPDAF.PDAF.assim.assim_offline_seik + - pyPDAF.PDAF.assim.assimilate_3dvar + - pyPDAF.PDAF.assim.assimilate_en3dvar_estkf + - pyPDAF.PDAF.assim.assimilate_en3dvar_lestkf + - pyPDAF.PDAF.assim.assimilate_enkf + - pyPDAF.PDAF.assim.assimilate_ensrf + - pyPDAF.PDAF.assim.assimilate_estkf + - pyPDAF.PDAF.assim.assimilate_etkf + - pyPDAF.PDAF.assim.assimilate_hyb3dvar_estkf + - pyPDAF.PDAF.assim.assimilate_hyb3dvar_lestkf + - pyPDAF.PDAF.assim.assimilate_lenkf + - pyPDAF.PDAF.assim.assimilate_lestkf + - pyPDAF.PDAF.assim.assimilate_letkf + - pyPDAF.PDAF.assim.assimilate_lknetf + - pyPDAF.PDAF.assim.assimilate_lnetf + - pyPDAF.PDAF.assim.assimilate_lseik + - pyPDAF.PDAF.assim.assimilate_netf + - pyPDAF.PDAF.assim.assimilate_pf + - pyPDAF.PDAF.assim.assimilate_prepost + - pyPDAF.PDAF.assim.assimilate_seik + - pyPDAF.PDAF.assim.generate_obs + - pyPDAF.PDAF.assim.generate_obs_offline + - pyPDAF.PDAF.assim.get_state + +### pyPDAF.PDAF.callback + - pyPDAF.PDAF.callback.add_obs_error_cb + - pyPDAF.PDAF.callback.g2l_obs_cb + - pyPDAF.PDAF.callback.init_obs_f_cb + - pyPDAF.PDAF.callback.init_obs_l_cb + - pyPDAF.PDAF.callback.init_obscovar_cb + - pyPDAF.PDAF.callback.init_obserr_f_cb + - pyPDAF.PDAF.callback.init_obsvar_cb + - pyPDAF.PDAF.callback.init_obsvar_l_cb + - pyPDAF.PDAF.callback.init_obsvars_f_cb + - pyPDAF.PDAF.callback.likelihood_cb + - pyPDAF.PDAF.callback.likelihood_hyb_l_cb + - pyPDAF.PDAF.callback.likelihood_l_cb + - pyPDAF.PDAF.callback.localize_covar_cb + - pyPDAF.PDAF.callback.localize_covar_serial_cb + - pyPDAF.PDAF.callback.omit_by_inno_cb + - pyPDAF.PDAF.callback.omit_by_inno_l_cb + - pyPDAF.PDAF.callback.prodrinva_cb + - pyPDAF.PDAF.callback.prodrinva_hyb_l_cb + - pyPDAF.PDAF.callback.prodrinva_l_cb + +### pyPDAF.PDAF.diag + - pyPDAF.PDAF.diag.diag_compute_moments + - pyPDAF.PDAF.diag.diag_crps_mpi + - pyPDAF.PDAF.diag.diag_crps_nompi + - pyPDAF.PDAF.diag.diag_effsample + - pyPDAF.PDAF.diag.diag_ensmean + - pyPDAF.PDAF.diag.diag_ensstats + - pyPDAF.PDAF.diag.diag_histogram + - pyPDAF.PDAF.diag.diag_reliability_budget + - pyPDAF.PDAF.diag.diag_rmsd + - pyPDAF.PDAF.diag.diag_rmsd_nompi + - pyPDAF.PDAF.diag.diag_stddev + - pyPDAF.PDAF.diag.diag_stddev_nompi + - pyPDAF.PDAF.diag.diag_variance + - pyPDAF.PDAF.diag.diag_variance_nompi + +### pyPDAF.PDAF.get + - pyPDAF.PDAF.get.get_assim_flag + - pyPDAF.PDAF.get.get_local_type + - pyPDAF.PDAF.get.get_localfilter + - pyPDAF.PDAF.get.get_memberid + - pyPDAF.PDAF.get.get_obsmemberid + - pyPDAF.PDAF.get.get_smoother_ens + +### pyPDAF.PDAF.iau_internal + - pyPDAF.PDAF.iau_internal.iau_add_inc_ens + - pyPDAF.PDAF.iau_internal.iau_dealloc + - pyPDAF.PDAF.iau_internal.iau_init_weights + - pyPDAF.PDAF.iau_internal.iau_update_ens + - pyPDAF.PDAF.iau_internal.iau_update_inc + +### pyPDAF.PDAF.iau + - pyPDAF.PDAF.iau.iau_add_inc + - pyPDAF.PDAF.iau.iau_init + - pyPDAF.PDAF.iau.iau_init_inc + - pyPDAF.PDAF.iau.iau_reset + - pyPDAF.PDAF.iau.iau_set_ens_pointer + - pyPDAF.PDAF.iau.iau_set_pointer + - pyPDAF.PDAF.iau.iau_set_state_pointer + - pyPDAF.PDAF.iau.iau_set_weights + +### pyPDAF.PDAF.internal + - pyPDAF.PDAF.internal._3dvar_alloc + - pyPDAF.PDAF.internal._3dvar_analysis_cvt + - pyPDAF.PDAF.internal._3dvar_config + - pyPDAF.PDAF.internal._3dvar_costf_cg_cvt + - pyPDAF.PDAF.internal._3dvar_costf_cvt + - pyPDAF.PDAF.internal._3dvar_init + - pyPDAF.PDAF.internal._3dvar_memtime + - pyPDAF.PDAF.internal._3dvar_optim_cg + - pyPDAF.PDAF.internal._3dvar_optim_cgplus + - pyPDAF.PDAF.internal._3dvar_optim_lbfgs + - pyPDAF.PDAF.internal._3dvar_options + - pyPDAF.PDAF.internal._3dvar_set_iparam + - pyPDAF.PDAF.internal._3dvar_set_rparam + - pyPDAF.PDAF.internal._3dvar_update + - pyPDAF.PDAF.internal.add_particle_noise + - pyPDAF.PDAF.internal.alloc + - pyPDAF.PDAF.internal.alloc_bias + - pyPDAF.PDAF.internal.alloc_filters + - pyPDAF.PDAF.internal.alloc_sens + - pyPDAF.PDAF.internal.allreduce + - pyPDAF.PDAF.internal.configinfo_filters + - pyPDAF.PDAF.internal.en3dvar_analysis_cvt + - pyPDAF.PDAF.internal.en3dvar_costf_cg_cvt + - pyPDAF.PDAF.internal.en3dvar_costf_cvt + - pyPDAF.PDAF.internal.en3dvar_optim_cg + - pyPDAF.PDAF.internal.en3dvar_optim_cgplus + - pyPDAF.PDAF.internal.en3dvar_optim_lbfgs + - pyPDAF.PDAF.internal.en3dvar_update_estkf + - pyPDAF.PDAF.internal.en3dvar_update_lestkf + - pyPDAF.PDAF.internal.enkf_alloc + - pyPDAF.PDAF.internal.enkf_ana_rlm + - pyPDAF.PDAF.internal.enkf_ana_rsm + - pyPDAF.PDAF.internal.enkf_config + - pyPDAF.PDAF.internal.enkf_gather_resid + - pyPDAF.PDAF.internal.enkf_init + - pyPDAF.PDAF.internal.enkf_memtime + - pyPDAF.PDAF.internal.enkf_obs_ensemble + - pyPDAF.PDAF.internal.enkf_options + - pyPDAF.PDAF.internal.enkf_set_iparam + - pyPDAF.PDAF.internal.enkf_set_rparam + - pyPDAF.PDAF.internal.enkf_update + - pyPDAF.PDAF.internal.ens_omega + - pyPDAF.PDAF.internal.ensrf_alloc + - pyPDAF.PDAF.internal.ensrf_ana + - pyPDAF.PDAF.internal.ensrf_ana_2step + - pyPDAF.PDAF.internal.ensrf_config + - pyPDAF.PDAF.internal.ensrf_init + - pyPDAF.PDAF.internal.ensrf_memtime + - pyPDAF.PDAF.internal.ensrf_options + - pyPDAF.PDAF.internal.ensrf_set_iparam + - pyPDAF.PDAF.internal.ensrf_set_rparam + - pyPDAF.PDAF.internal.ensrf_update + - pyPDAF.PDAF.internal.estkf_alloc + - pyPDAF.PDAF.internal.estkf_ana + - pyPDAF.PDAF.internal.estkf_ana_fixed + - pyPDAF.PDAF.internal.estkf_aomega + - pyPDAF.PDAF.internal.estkf_config + - pyPDAF.PDAF.internal.estkf_init + - pyPDAF.PDAF.internal.estkf_memtime + - pyPDAF.PDAF.internal.estkf_omegaa + - pyPDAF.PDAF.internal.estkf_options + - pyPDAF.PDAF.internal.estkf_set_iparam + - pyPDAF.PDAF.internal.estkf_set_rparam + - pyPDAF.PDAF.internal.estkf_update + - pyPDAF.PDAF.internal.etkf_alloc + - pyPDAF.PDAF.internal.etkf_ana + - pyPDAF.PDAF.internal.etkf_ana_fixed + - pyPDAF.PDAF.internal.etkf_ana_t + - pyPDAF.PDAF.internal.etkf_config + - pyPDAF.PDAF.internal.etkf_init + - pyPDAF.PDAF.internal.etkf_memtime + - pyPDAF.PDAF.internal.etkf_options + - pyPDAF.PDAF.internal.etkf_set_iparam + - pyPDAF.PDAF.internal.etkf_set_rparam + - pyPDAF.PDAF.internal.etkf_update + - pyPDAF.PDAF.internal.fcst_operations + - pyPDAF.PDAF.internal.gather_ens + - pyPDAF.PDAF.internal.gen_obs + - pyPDAF.PDAF.internal.generate_rndmat + - pyPDAF.PDAF.internal.genobs_alloc + - pyPDAF.PDAF.internal.genobs_config + - pyPDAF.PDAF.internal.genobs_init + - pyPDAF.PDAF.internal.genobs_options + - pyPDAF.PDAF.internal.genobs_set_iparam + - pyPDAF.PDAF.internal.get_ensstats + - pyPDAF.PDAF.internal.hyb3dvar_analysis_cvt + - pyPDAF.PDAF.internal.hyb3dvar_costf_cg_cvt + - pyPDAF.PDAF.internal.hyb3dvar_costf_cvt + - pyPDAF.PDAF.internal.hyb3dvar_optim_cg + - pyPDAF.PDAF.internal.hyb3dvar_optim_cgplus + - pyPDAF.PDAF.internal.hyb3dvar_optim_lbfgs + - pyPDAF.PDAF.internal.hyb3dvar_update_estkf + - pyPDAF.PDAF.internal.hyb3dvar_update_lestkf + - pyPDAF.PDAF.internal.incr_local_obsstats + - pyPDAF.PDAF.internal.inflate_ens + - pyPDAF.PDAF.internal.inflate_weights + - pyPDAF.PDAF.internal.init_filters + - pyPDAF.PDAF.internal.init_local_obsstats + - pyPDAF.PDAF.internal.init_parallel + - pyPDAF.PDAF.internal.lenkf_alloc + - pyPDAF.PDAF.internal.lenkf_ana_rsm + - pyPDAF.PDAF.internal.lenkf_config + - pyPDAF.PDAF.internal.lenkf_init + - pyPDAF.PDAF.internal.lenkf_memtime + - pyPDAF.PDAF.internal.lenkf_options + - pyPDAF.PDAF.internal.lenkf_set_iparam + - pyPDAF.PDAF.internal.lenkf_set_rparam + - pyPDAF.PDAF.internal.lenkf_update + - pyPDAF.PDAF.internal.lestkf_alloc + - pyPDAF.PDAF.internal.lestkf_ana + - pyPDAF.PDAF.internal.lestkf_ana_fixed + - pyPDAF.PDAF.internal.lestkf_config + - pyPDAF.PDAF.internal.lestkf_init + - pyPDAF.PDAF.internal.lestkf_memtime + - pyPDAF.PDAF.internal.lestkf_options + - pyPDAF.PDAF.internal.lestkf_set_iparam + - pyPDAF.PDAF.internal.lestkf_set_rparam + - pyPDAF.PDAF.internal.lestkf_update + - pyPDAF.PDAF.internal.letkf_alloc + - pyPDAF.PDAF.internal.letkf_ana + - pyPDAF.PDAF.internal.letkf_ana_fixed + - pyPDAF.PDAF.internal.letkf_ana_t + - pyPDAF.PDAF.internal.letkf_config + - pyPDAF.PDAF.internal.letkf_init + - pyPDAF.PDAF.internal.letkf_memtime + - pyPDAF.PDAF.internal.letkf_options + - pyPDAF.PDAF.internal.letkf_set_iparam + - pyPDAF.PDAF.internal.letkf_set_rparam + - pyPDAF.PDAF.internal.letkf_update + - pyPDAF.PDAF.internal.lknetf_alloc + - pyPDAF.PDAF.internal.lknetf_alpha_neff + - pyPDAF.PDAF.internal.lknetf_ana_letkft + - pyPDAF.PDAF.internal.lknetf_ana_lnetf + - pyPDAF.PDAF.internal.lknetf_analysis_t + - pyPDAF.PDAF.internal.lknetf_compute_gamma + - pyPDAF.PDAF.internal.lknetf_config + - pyPDAF.PDAF.internal.lknetf_init + - pyPDAF.PDAF.internal.lknetf_memtime + - pyPDAF.PDAF.internal.lknetf_options + - pyPDAF.PDAF.internal.lknetf_reset_gamma + - pyPDAF.PDAF.internal.lknetf_set_gamma + - pyPDAF.PDAF.internal.lknetf_set_iparam + - pyPDAF.PDAF.internal.lknetf_set_rparam + - pyPDAF.PDAF.internal.lknetf_update_step + - pyPDAF.PDAF.internal.lknetf_update_sync + - pyPDAF.PDAF.internal.lnetf_alloc + - pyPDAF.PDAF.internal.lnetf_ana + - pyPDAF.PDAF.internal.lnetf_config + - pyPDAF.PDAF.internal.lnetf_init + - pyPDAF.PDAF.internal.lnetf_memtime + - pyPDAF.PDAF.internal.lnetf_options + - pyPDAF.PDAF.internal.lnetf_set_iparam + - pyPDAF.PDAF.internal.lnetf_set_rparam + - pyPDAF.PDAF.internal.lnetf_smoothert + - pyPDAF.PDAF.internal.lnetf_update + - pyPDAF.PDAF.internal.lseik_alloc + - pyPDAF.PDAF.internal.lseik_ana + - pyPDAF.PDAF.internal.lseik_ana_trans + - pyPDAF.PDAF.internal.lseik_config + - pyPDAF.PDAF.internal.lseik_init + - pyPDAF.PDAF.internal.lseik_memtime + - pyPDAF.PDAF.internal.lseik_options + - pyPDAF.PDAF.internal.lseik_resample + - pyPDAF.PDAF.internal.lseik_set_iparam + - pyPDAF.PDAF.internal.lseik_set_rparam + - pyPDAF.PDAF.internal.lseik_update + - pyPDAF.PDAF.internal.memcount + - pyPDAF.PDAF.internal.memcount_define + - pyPDAF.PDAF.internal.memcount_ini + - pyPDAF.PDAF.internal.mpi_init + - pyPDAF.PDAF.internal.mvnormalize + - pyPDAF.PDAF.internal.netf_alloc + - pyPDAF.PDAF.internal.netf_ana + - pyPDAF.PDAF.internal.netf_config + - pyPDAF.PDAF.internal.netf_init + - pyPDAF.PDAF.internal.netf_memtime + - pyPDAF.PDAF.internal.netf_options + - pyPDAF.PDAF.internal.netf_set_iparam + - pyPDAF.PDAF.internal.netf_set_rparam + - pyPDAF.PDAF.internal.netf_smoothert + - pyPDAF.PDAF.internal.netf_update + - pyPDAF.PDAF.internal.obs_dealloc + - pyPDAF.PDAF.internal.obs_dealloc_local + - pyPDAF.PDAF.internal.obs_init + - pyPDAF.PDAF.internal.obs_init_local + - pyPDAF.PDAF.internal.obs_init_obsvars + - pyPDAF.PDAF.internal.options_filters + - pyPDAF.PDAF.internal.pf_alloc + - pyPDAF.PDAF.internal.pf_ana + - pyPDAF.PDAF.internal.pf_config + - pyPDAF.PDAF.internal.pf_init + - pyPDAF.PDAF.internal.pf_memtime + - pyPDAF.PDAF.internal.pf_options + - pyPDAF.PDAF.internal.pf_resampling + - pyPDAF.PDAF.internal.pf_set_iparam + - pyPDAF.PDAF.internal.pf_set_rparam + - pyPDAF.PDAF.internal.pf_update + - pyPDAF.PDAF.internal.prepost + - pyPDAF.PDAF.internal.print_domain_stats + - pyPDAF.PDAF.internal.print_info_filters + - pyPDAF.PDAF.internal.print_local_obsstats + - pyPDAF.PDAF.internal.print_version + - pyPDAF.PDAF.internal.reset_dim_ens + - pyPDAF.PDAF.internal.reset_dim_p + - pyPDAF.PDAF.internal.scatter_ens + - pyPDAF.PDAF.internal.seik_alloc + - pyPDAF.PDAF.internal.seik_ana + - pyPDAF.PDAF.internal.seik_ana_newt + - pyPDAF.PDAF.internal.seik_ana_trans + - pyPDAF.PDAF.internal.seik_config + - pyPDAF.PDAF.internal.seik_init + - pyPDAF.PDAF.internal.seik_matrixt + - pyPDAF.PDAF.internal.seik_memtime + - pyPDAF.PDAF.internal.seik_omega + - pyPDAF.PDAF.internal.seik_options + - pyPDAF.PDAF.internal.seik_resample + - pyPDAF.PDAF.internal.seik_resample_newt + - pyPDAF.PDAF.internal.seik_set_iparam + - pyPDAF.PDAF.internal.seik_set_rparam + - pyPDAF.PDAF.internal.seik_ttimesa + - pyPDAF.PDAF.internal.seik_uinv + - pyPDAF.PDAF.internal.seik_update + - pyPDAF.PDAF.internal.set_forget + - pyPDAF.PDAF.internal.set_forget_local + - pyPDAF.PDAF.internal.set_iparam_filters + - pyPDAF.PDAF.internal.set_rparam_filters + - pyPDAF.PDAF.internal.sisort + - pyPDAF.PDAF.internal.smoother_enkf + - pyPDAF.PDAF.internal.smoother_lnetf + - pyPDAF.PDAF.internal.smoother_netf + - pyPDAF.PDAF.internal.smoother_shift + - pyPDAF.PDAF.internal.smoothing + - pyPDAF.PDAF.internal.smoothing_local + - pyPDAF.PDAF.internal.subtract_colmean + - pyPDAF.PDAF.internal.subtract_rowmean + - pyPDAF.PDAF.internal.timeit + +### pyPDAF.PDAF.put + - pyPDAF.PDAF.put.put_state_3dvar + - pyPDAF.PDAF.put.put_state_en3dvar_estkf + - pyPDAF.PDAF.put.put_state_en3dvar_lestkf + - pyPDAF.PDAF.put.put_state_enkf + - pyPDAF.PDAF.put.put_state_ensrf + - pyPDAF.PDAF.put.put_state_estkf + - pyPDAF.PDAF.put.put_state_etkf + - pyPDAF.PDAF.put.put_state_generate_obs + - pyPDAF.PDAF.put.put_state_hyb3dvar_estkf + - pyPDAF.PDAF.put.put_state_hyb3dvar_lestkf + - pyPDAF.PDAF.put.put_state_lenkf + - pyPDAF.PDAF.put.put_state_lestkf + - pyPDAF.PDAF.put.put_state_letkf + - pyPDAF.PDAF.put.put_state_lknetf + - pyPDAF.PDAF.put.put_state_lnetf + - pyPDAF.PDAF.put.put_state_lseik + - pyPDAF.PDAF.put.put_state_netf + - pyPDAF.PDAF.put.put_state_pf + - pyPDAF.PDAF.put.put_state_prepost + - pyPDAF.PDAF.put.put_state_seik + +### pyPDAF.PDAF.setter + - pyPDAF.PDAF.setter.set_comm_pdaf + - pyPDAF.PDAF.setter.set_debug_flag + - pyPDAF.PDAF.setter.set_ens_pointer + - pyPDAF.PDAF.setter.set_iparam + - pyPDAF.PDAF.setter.set_memberid + - pyPDAF.PDAF.setter.set_offline_mode + - pyPDAF.PDAF.setter.set_rparam + - pyPDAF.PDAF.setter.set_seedset + - pyPDAF.PDAF.setter.set_smoother_ens + +## pyPDAF.PDAF3 +### pyPDAF.PDAF3._pdaf3_c + - pyPDAF.PDAF3._pdaf3_c.init + - pyPDAF.PDAF3._pdaf3_c.init_forecast + - pyPDAF.PDAF3._pdaf3_c.set_parallel + +### pyPDAF.PDAF3.assim + - pyPDAF.PDAF3.assim.assim_offline + - pyPDAF.PDAF3.assim.assim_offline_3dvar + - pyPDAF.PDAF3.assim.assim_offline_3dvar_all + - pyPDAF.PDAF3.assim.assim_offline_3dvar_nondiagr + - pyPDAF.PDAF3.assim.assim_offline_en3dvar + - pyPDAF.PDAF3.assim.assim_offline_en3dvar_estkf + - pyPDAF.PDAF3.assim.assim_offline_en3dvar_estkf_nondiagr + - pyPDAF.PDAF3.assim.assim_offline_en3dvar_lestkf + - pyPDAF.PDAF3.assim.assim_offline_en3dvar_lestkf_nondiagr + - pyPDAF.PDAF3.assim.assim_offline_enkf_nondiagr + - pyPDAF.PDAF3.assim.assim_offline_ensrf + - pyPDAF.PDAF3.assim.assim_offline_global + - pyPDAF.PDAF3.assim.assim_offline_global_nondiagr + - pyPDAF.PDAF3.assim.assim_offline_hyb3dvar + - pyPDAF.PDAF3.assim.assim_offline_hyb3dvar_estkf + - pyPDAF.PDAF3.assim.assim_offline_hyb3dvar_estkf_nondiagr + - pyPDAF.PDAF3.assim.assim_offline_hyb3dvar_lestkf + - pyPDAF.PDAF3.assim.assim_offline_hyb3dvar_lestkf_nondiagr + - pyPDAF.PDAF3.assim.assim_offline_lenkf + - pyPDAF.PDAF3.assim.assim_offline_lenkf_nondiagr + - pyPDAF.PDAF3.assim.assim_offline_lknetf_nondiagr + - pyPDAF.PDAF3.assim.assim_offline_lnetf_nondiagr + - pyPDAF.PDAF3.assim.assim_offline_local + - pyPDAF.PDAF3.assim.assim_offline_local_nondiagr + - pyPDAF.PDAF3.assim.assim_offline_nonlin_nondiagr + - pyPDAF.PDAF3.assim.assimilate + - pyPDAF.PDAF3.assim.assimilate_3dvar + - pyPDAF.PDAF3.assim.assimilate_3dvar_all + - pyPDAF.PDAF3.assim.assimilate_3dvar_nondiagr + - pyPDAF.PDAF3.assim.assimilate_en3dvar + - pyPDAF.PDAF3.assim.assimilate_en3dvar_estkf + - pyPDAF.PDAF3.assim.assimilate_en3dvar_estkf_nondiagr + - pyPDAF.PDAF3.assim.assimilate_en3dvar_lestkf + - pyPDAF.PDAF3.assim.assimilate_en3dvar_lestkf_nondiagr + - pyPDAF.PDAF3.assim.assimilate_enkf_nondiagr + - pyPDAF.PDAF3.assim.assimilate_ensrf + - pyPDAF.PDAF3.assim.assimilate_global + - pyPDAF.PDAF3.assim.assimilate_global_nondiagr + - pyPDAF.PDAF3.assim.assimilate_hyb3dvar + - pyPDAF.PDAF3.assim.assimilate_hyb3dvar_estkf + - pyPDAF.PDAF3.assim.assimilate_hyb3dvar_estkf_nondiagr + - pyPDAF.PDAF3.assim.assimilate_hyb3dvar_lestkf + - pyPDAF.PDAF3.assim.assimilate_hyb3dvar_lestkf_nondiagr + - pyPDAF.PDAF3.assim.assimilate_lenkf + - pyPDAF.PDAF3.assim.assimilate_lenkf_nondiagr + - pyPDAF.PDAF3.assim.assimilate_lknetf_nondiagr + - pyPDAF.PDAF3.assim.assimilate_lnetf_nondiagr + - pyPDAF.PDAF3.assim.assimilate_local + - pyPDAF.PDAF3.assim.assimilate_local_nondiagr + - pyPDAF.PDAF3.assim.assimilate_nonlin_nondiagr + - pyPDAF.PDAF3.assim.generate_obs + - pyPDAF.PDAF3.assim.generate_obs_offline + +### pyPDAF.PDAF3.put + - pyPDAF.PDAF3.put.put_state + - pyPDAF.PDAF3.put.put_state_3dvar + - pyPDAF.PDAF3.put.put_state_3dvar_all + - pyPDAF.PDAF3.put.put_state_3dvar_nondiagr + - pyPDAF.PDAF3.put.put_state_en3dvar + - pyPDAF.PDAF3.put.put_state_en3dvar_estkf + - pyPDAF.PDAF3.put.put_state_en3dvar_estkf_nondiagr + - pyPDAF.PDAF3.put.put_state_en3dvar_lestkf + - pyPDAF.PDAF3.put.put_state_en3dvar_lestkf_nondiagr + - pyPDAF.PDAF3.put.put_state_enkf_nondiagr + - pyPDAF.PDAF3.put.put_state_ensrf + - pyPDAF.PDAF3.put.put_state_generate_obs + - pyPDAF.PDAF3.put.put_state_global + - pyPDAF.PDAF3.put.put_state_global_nondiagr + - pyPDAF.PDAF3.put.put_state_hyb3dvar + - pyPDAF.PDAF3.put.put_state_hyb3dvar_estkf + - pyPDAF.PDAF3.put.put_state_hyb3dvar_estkf_nondiagr + - pyPDAF.PDAF3.put.put_state_hyb3dvar_lestkf + - pyPDAF.PDAF3.put.put_state_hyb3dvar_lestkf_nondiagr + - pyPDAF.PDAF3.put.put_state_lenkf + - pyPDAF.PDAF3.put.put_state_lenkf_nondiagr + - pyPDAF.PDAF3.put.put_state_lknetf_nondiagr + - pyPDAF.PDAF3.put.put_state_lnetf_nondiagr + - pyPDAF.PDAF3.put.put_state_local + - pyPDAF.PDAF3.put.put_state_local_nondiagr + - pyPDAF.PDAF3.put.put_state_nonlin_nondiagr + +## pyPDAF.PDAFlocal +### pyPDAF.PDAFlocal._pdaflocal_c + - pyPDAF.PDAFlocal._pdaflocal_c.clear_increment_weights + - pyPDAF.PDAFlocal._pdaflocal_c.set_increment_weights + - pyPDAF.PDAFlocal._pdaflocal_c.set_indices + +### pyPDAF.PDAFlocal.assim + - pyPDAF.PDAFlocal.assim.assimilate_en3dvar_lestkf + - pyPDAF.PDAFlocal.assim.assimilate_hyb3dvar_lestkf + - pyPDAF.PDAFlocal.assim.assimilate_lestkf + - pyPDAF.PDAFlocal.assim.assimilate_letkf + - pyPDAF.PDAFlocal.assim.assimilate_lknetf + - pyPDAF.PDAFlocal.assim.assimilate_lnetf + - pyPDAF.PDAFlocal.assim.assimilate_lseik + +### pyPDAF.PDAFlocal.internal + - pyPDAF.PDAFlocal.internal.g2l_cb + - pyPDAF.PDAFlocal.internal.l2g_cb + +### pyPDAF.PDAFlocal.put + - pyPDAF.PDAFlocal.put.put_state_en3dvar_lestkf + - pyPDAF.PDAFlocal.put.put_state_hyb3dvar_lestkf + - pyPDAF.PDAFlocal.put.put_state_lestkf + - pyPDAF.PDAFlocal.put.put_state_letkf + - pyPDAF.PDAFlocal.put.put_state_lknetf + - pyPDAF.PDAFlocal.put.put_state_lnetf + - pyPDAF.PDAFlocal.put.put_state_lseik + +## pyPDAF.PDAFlocalomi +### pyPDAF.PDAFlocalomi.assim + - pyPDAF.PDAFlocalomi.assim.assimilate + - pyPDAF.PDAFlocalomi.assim.assimilate_en3dvar_lestkf + - pyPDAF.PDAFlocalomi.assim.assimilate_en3dvar_lestkf_nondiagr + - pyPDAF.PDAFlocalomi.assim.assimilate_hyb3dvar_lestkf + - pyPDAF.PDAFlocalomi.assim.assimilate_hyb3dvar_lestkf_nondiagr + - pyPDAF.PDAFlocalomi.assim.assimilate_lknetf_nondiagr + - pyPDAF.PDAFlocalomi.assim.assimilate_lnetf_nondiagr + - pyPDAF.PDAFlocalomi.assim.assimilate_nondiagr + +### pyPDAF.PDAFlocalomi.put + - pyPDAF.PDAFlocalomi.put.put_state + - pyPDAF.PDAFlocalomi.put.put_state_en3dvar_lestkf + - pyPDAF.PDAFlocalomi.put.put_state_en3dvar_lestkf_nondiagr + - pyPDAF.PDAFlocalomi.put.put_state_hyb3dvar_lestkf + - pyPDAF.PDAFlocalomi.put.put_state_hyb3dvar_lestkf_nondiagr + - pyPDAF.PDAFlocalomi.put.put_state_lknetf_nondiagr + - pyPDAF.PDAFlocalomi.put.put_state_lnetf_nondiagr + - pyPDAF.PDAFlocalomi.put.put_state_nondiagr + + +## pyPDAF.PDAFomi +### pyPDAF.PDAFomi._pdafomi_c + - pyPDAF.PDAFomi._pdafomi_c.check_error + - pyPDAF.PDAFomi._pdafomi_c.gather_obs + - pyPDAF.PDAFomi._pdafomi_c.gather_obsstate + - pyPDAF.PDAFomi._pdafomi_c.get_domain_limits_unstr + - pyPDAF.PDAFomi._pdafomi_c.get_interp_coeff_lin + - pyPDAF.PDAFomi._pdafomi_c.get_interp_coeff_lin1d + - pyPDAF.PDAFomi._pdafomi_c.get_interp_coeff_tri + - pyPDAF.PDAFomi._pdafomi_c.init + - pyPDAF.PDAFomi._pdafomi_c.init_dim_obs_l_iso + - pyPDAF.PDAFomi._pdafomi_c.init_dim_obs_l_noniso + - pyPDAF.PDAFomi._pdafomi_c.init_dim_obs_l_noniso_locweights + - pyPDAF.PDAFomi._pdafomi_c.init_local + - pyPDAF.PDAFomi._pdafomi_c.obs_op_adj_gridavg + - pyPDAF.PDAFomi._pdafomi_c.obs_op_adj_gridpoint + - pyPDAF.PDAFomi._pdafomi_c.obs_op_adj_interp_lin + - pyPDAF.PDAFomi._pdafomi_c.obs_op_extern + - pyPDAF.PDAFomi._pdafomi_c.obs_op_gridavg + - pyPDAF.PDAFomi._pdafomi_c.obs_op_gridpoint + - pyPDAF.PDAFomi._pdafomi_c.obs_op_interp_lin + - pyPDAF.PDAFomi._pdafomi_c.observation_localization_weights + - pyPDAF.PDAFomi._pdafomi_c.set_debug_flag + - pyPDAF.PDAFomi._pdafomi_c.set_dim_obs_l + - pyPDAF.PDAFomi._pdafomi_c.set_domain_limits + - pyPDAF.PDAFomi._pdafomi_c.set_localization + - pyPDAF.PDAFomi._pdafomi_c.set_localization_noniso + - pyPDAF.PDAFomi._pdafomi_c.set_localize_covar_iso + - pyPDAF.PDAFomi._pdafomi_c.set_localize_covar_noniso + - pyPDAF.PDAFomi._pdafomi_c.set_localize_covar_noniso_locweights + - pyPDAF.PDAFomi._pdafomi_c.set_obs_diag + - pyPDAF.PDAFomi._pdafomi_c.store_obs_l_index + - pyPDAF.PDAFomi._pdafomi_c.store_obs_l_index_vdist + +### pyPDAF.PDAFomi.assim + - pyPDAF.PDAFomi.assim.assimilate_3dvar + - pyPDAF.PDAFomi.assim.assimilate_3dvar_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_en3dvar_estkf + - pyPDAF.PDAFomi.assim.assimilate_en3dvar_estkf_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_en3dvar_lestkf + - pyPDAF.PDAFomi.assim.assimilate_en3dvar_lestkf_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_enkf_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_ensrf + - pyPDAF.PDAFomi.assim.assimilate_global + - pyPDAF.PDAFomi.assim.assimilate_global_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_hyb3dvar_estkf + - pyPDAF.PDAFomi.assim.assimilate_hyb3dvar_estkf_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_hyb3dvar_lestkf + - pyPDAF.PDAFomi.assim.assimilate_hyb3dvar_lestkf_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_lenkf + - pyPDAF.PDAFomi.assim.assimilate_lenkf_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_lknetf_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_lnetf_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_local + - pyPDAF.PDAFomi.assim.assimilate_local_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_nonlin_nondiagr + - pyPDAF.PDAFomi.assim.generate_obs + +### pyPDAF.PDAFomi.diag + - pyPDAF.PDAFomi.diag.diag_dimobs + - pyPDAF.PDAFomi.diag.diag_get_hx + - pyPDAF.PDAFomi.diag.diag_get_hxmean + - pyPDAF.PDAFomi.diag.diag_get_ivar + - pyPDAF.PDAFomi.diag.diag_get_obs + - pyPDAF.PDAFomi.diag.diag_nobstypes + - pyPDAF.PDAFomi.diag.diag_obs_rmsd + - pyPDAF.PDAFomi.diag.diag_stats + +### pyPDAF.PDAFomi.internal + - pyPDAF.PDAFomi.internal.add_obs_error + - pyPDAF.PDAFomi.internal.check_dist2 + - pyPDAF.PDAFomi.internal.check_dist2_loop + - pyPDAF.PDAFomi.internal.check_dist2_noniso + - pyPDAF.PDAFomi.internal.check_dist2_noniso_loop + - pyPDAF.PDAFomi.internal.cnt_dim_obs_l + - pyPDAF.PDAFomi.internal.cnt_dim_obs_l_noniso + - pyPDAF.PDAFomi.internal.comp_dist2 + - pyPDAF.PDAFomi.internal.dealloc + - pyPDAF.PDAFomi.internal.diag_omit_by_inno + - pyPDAF.PDAFomi.internal.g2l_obs + - pyPDAF.PDAFomi.internal.g2l_obs_internal + - pyPDAF.PDAFomi.internal.gather_dim_obs_f + - pyPDAF.PDAFomi.internal.gather_obs_f2_flex + - pyPDAF.PDAFomi.internal.gather_obs_f_flex + - pyPDAF.PDAFomi.internal.gather_obsdims + - pyPDAF.PDAFomi.internal.get_local_ids_obs_f + - pyPDAF.PDAFomi.internal.init_obs_f + - pyPDAF.PDAFomi.internal.init_obs_l + - pyPDAF.PDAFomi.internal.init_obsarrays_l + - pyPDAF.PDAFomi.internal.init_obsarrays_l_noniso + - pyPDAF.PDAFomi.internal.init_obscovar + - pyPDAF.PDAFomi.internal.init_obserr_f + - pyPDAF.PDAFomi.internal.init_obsvar_f + - pyPDAF.PDAFomi.internal.init_obsvar_l + - pyPDAF.PDAFomi.internal.init_obsvars_f + - pyPDAF.PDAFomi.internal.likelihood + - pyPDAF.PDAFomi.internal.likelihood_hyb_l + - pyPDAF.PDAFomi.internal.likelihood_l + - pyPDAF.PDAFomi.internal.limit_obs_f + - pyPDAF.PDAFomi.internal.local_weight + - pyPDAF.PDAFomi.internal.obs_op_adj_gatheronly + - pyPDAF.PDAFomi.internal.obs_op_gatheronly + - pyPDAF.PDAFomi.internal.obsstats + - pyPDAF.PDAFomi.internal.obsstats_l + - pyPDAF.PDAFomi.internal.ocoord_all + - pyPDAF.PDAFomi.internal.omit_by_inno + - pyPDAF.PDAFomi.internal.omit_by_inno_l + - pyPDAF.PDAFomi.internal.prodrinva + - pyPDAF.PDAFomi.internal.prodrinva_hyb_l + - pyPDAF.PDAFomi.internal.prodrinva_l + - pyPDAF.PDAFomi.internal.set_globalobs + - pyPDAF.PDAFomi.internal.weights_l + - pyPDAF.PDAFomi.internal.weights_l_sgnl + +### pyPDAF.PDAFomi.legacy + - pyPDAF.PDAFomi.legacy.deallocate_obs + - pyPDAF.PDAFomi.legacy.init_dim_obs_l_iso_old + - pyPDAF.PDAFomi.legacy.init_dim_obs_l_noniso_locweights_old + - pyPDAF.PDAFomi.legacy.init_dim_obs_l_noniso_old + - pyPDAF.PDAFomi.legacy.localize_covar_iso + - pyPDAF.PDAFomi.legacy.localize_covar_noniso + - pyPDAF.PDAFomi.legacy.localize_covar_noniso_locweights + - pyPDAF.PDAFomi.legacy.localize_covar_serial_iso + - pyPDAF.PDAFomi.legacy.localize_covar_serial_noniso + - pyPDAF.PDAFomi.legacy.localize_covar_serial_noniso_locweights + +### pyPDAF.PDAFomi.assim + - pyPDAF.PDAFomi.assim.assimilate_3dvar + - pyPDAF.PDAFomi.assim.assimilate_3dvar_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_en3dvar_estkf + - pyPDAF.PDAFomi.assim.assimilate_en3dvar_estkf_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_en3dvar_lestkf + - pyPDAF.PDAFomi.assim.assimilate_en3dvar_lestkf_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_enkf_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_ensrf + - pyPDAF.PDAFomi.assim.assimilate_global + - pyPDAF.PDAFomi.assim.assimilate_global_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_hyb3dvar_estkf + - pyPDAF.PDAFomi.assim.assimilate_hyb3dvar_estkf_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_hyb3dvar_lestkf + - pyPDAF.PDAFomi.assim.assimilate_hyb3dvar_lestkf_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_lenkf + - pyPDAF.PDAFomi.assim.assimilate_lenkf_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_lknetf_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_lnetf_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_local + - pyPDAF.PDAFomi.assim.assimilate_local_nondiagr + - pyPDAF.PDAFomi.assim.assimilate_nonlin_nondiagr + - pyPDAF.PDAFomi.assim.generate_obs + +### pyPDAF.PDAFomi.put + - pyPDAF.PDAFomi.put.put_state_3dvar + - pyPDAF.PDAFomi.put.put_state_3dvar_nondiagr + - pyPDAF.PDAFomi.put.put_state_en3dvar_estkf + - pyPDAF.PDAFomi.put.put_state_en3dvar_estkf_nondiagr + - pyPDAF.PDAFomi.put.put_state_en3dvar_lestkf + - pyPDAF.PDAFomi.put.put_state_en3dvar_lestkf_nondiagr + - pyPDAF.PDAFomi.put.put_state_enkf_nondiagr + - pyPDAF.PDAFomi.put.put_state_ensrf + - pyPDAF.PDAFomi.put.put_state_generate_obs + - pyPDAF.PDAFomi.put.put_state_global + - pyPDAF.PDAFomi.put.put_state_global_nondiagr + - pyPDAF.PDAFomi.put.put_state_hyb3dvar_estkf + - pyPDAF.PDAFomi.put.put_state_hyb3dvar_estkf_nondiagr + - pyPDAF.PDAFomi.put.put_state_hyb3dvar_lestkf + - pyPDAF.PDAFomi.put.put_state_hyb3dvar_lestkf_nondiagr + - pyPDAF.PDAFomi.put.put_state_lenkf + - pyPDAF.PDAFomi.put.put_state_lenkf_nondiagr + - pyPDAF.PDAFomi.put.put_state_lknetf_nondiagr + - pyPDAF.PDAFomi.put.put_state_lnetf_nondiagr + - pyPDAF.PDAFomi.put.put_state_local + - pyPDAF.PDAFomi.put.put_state_local_nondiagr + - pyPDAF.PDAFomi.put.put_state_nonlin_nondiagr + +### pyPDAF.PDAFomi.setter + - pyPDAF.PDAFomi.setter.set_disttype + - pyPDAF.PDAFomi.setter.set_doassim + - pyPDAF.PDAFomi.setter.set_domainsize + - pyPDAF.PDAFomi.setter.set_icoeff_p + - pyPDAF.PDAFomi.setter.set_id_obs_p + - pyPDAF.PDAFomi.setter.set_inno_omit + - pyPDAF.PDAFomi.setter.set_inno_omit_ivar + - pyPDAF.PDAFomi.setter.set_name + - pyPDAF.PDAFomi.setter.set_ncoord + - pyPDAF.PDAFomi.setter.set_obs_err_type + - pyPDAF.PDAFomi.setter.set_use_global_obs \ No newline at end of file diff --git a/pyPDAF/source/docs/source/index.rst b/pyPDAF/source/docs/source/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..e8c605eee6b4b290806f82204c22fa12a23f059d --- /dev/null +++ b/pyPDAF/source/docs/source/index.rst @@ -0,0 +1,21 @@ +.. pyPDAF documentation master file, created by + sphinx-quickstart on Mon May 9 15:24:06 2022. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +pyPDAF - A Python interface to Parallel Data Assimilation Framework +=================================================================== +.. include:: introduction.md + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + install + naming_convention + parallel + develop + API + user_functions + hidden_functions + links \ No newline at end of file diff --git a/pyPDAF/source/docs/source/install.md b/pyPDAF/source/docs/source/install.md new file mode 100644 index 0000000000000000000000000000000000000000..de86cfbcd73aa8ee8dd509d8ad9cb07e2fff4484 --- /dev/null +++ b/pyPDAF/source/docs/source/install.md @@ -0,0 +1,74 @@ + +# Installation + +There are two ways of installing pyPDAF. + +## Conda +The easiest approach is using `conda`. Currently, `pyPDAF` is available from +`conda` for `Windows`, `Linux` and `MacOS`. The installation can be obtained via: +```bash +conda create -n pypdaf -c conda-forge yumengch::pypdaf +``` +After installation, `pyPDAF` can be used by activating the conda environment +`conda activate pypdaf`. + +## Source code +In some cases, it is desirable to compile pyPDAF so that one can use their +favourite compiler as well as MPI and BLAS implementation. + +In this case, pyPDAF source code can be obtained from source +```bash +git clone --recurse-submodules https://github.com/yumengch/pyPDAF.git +cd pyPDAF +``` + +The package can be installed with: +```bash +python -m pip install . -v \ + --config-settings=setup-args="-Dblas_lib=[LIBS]" \ + --config-settings=setup-args="-Dincdirs=[INCDIRS]" \ + --config-settings=setup-args="-Dlibdirs=[LIBDIRS]" \ + --config-settings=setup-args="-Dmpi_mod=MPIF90"^ + --config-settings=setup-args="-Dbuildtype=release" +``` +Here, `LIBS`, `INCDIRS`, and `LIBDIRS` are elements of a list, separated by +`,` similar to a Python list. + - `LIBS` are all the required library names for BLAS libraries. + - `LIBDIRS` are directories of these libraries + - `INCDIRS` are include directories of libraries + - `MPIF90` is the path to `mpi.f90`. This is useful for the case where + `mpi.mod` is not directly provided but requires compiling by the user. This + is optional. + +One can adjust the compiler, compiler and linker flags by changing environment +variables such as `CC`, `FC`, `CFLAGS` and `FCFLAGS`. See [flags](https://mesonbuild.com/Reference-tables.html#compiler-and-linker-flag-environment-variables) and [compiler](https://mesonbuild.com/Reference-tables.html#compiler-and-linker-selection-variables) table for references. One could also directly +modify [`meson.build`](https://github.com/yumengch/pyPDAF/blob/main/meson.build) which might require more knowledge of meson. + +An example of installing pyPDAF in Linux or Mac: +```bash +CC=mpicc FC=mpifort python -m pip install . -v -Cbuild-dir=build \ + --config-settings=setup-args="-Dblas_lib=['openblas']" \ + --config-settings=setup-args="-Dincdirs=['/usr/lib/']" \ + --config-settings=setup-args="-Dlibdirs=['/usr/include']" \ + --config-settings=setup-args="-Dbuildtype=release" +``` +In Windows, one can use +```console +set CXX=clang-cl +set CC=clang-cl +set FC=flang-new +set MSMPI_INC=C:\Program Files (x86)\Microsoft SDKs\MPI\Include +set MSMPI_LIB64=C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x64 + +python -m pip install . -v ^ + -Cbuild-dir=build --config-settings=setup-args="-Dblas_lib=openblas"^ + --config-settings=setup-args="-Dincdirs="C:\Program Files (x86)\blas\include"^ + --config-settings=setup-args="-Dlibdirs="C:\Program Files (x86)\blas\lib"^ + --config-settings=setup-args="-Dmpi_mod=C:\Program Files (x86)\Microsoft SDKs\MPI\Include\mpi.f90"^ + --config-settings=setup-args="-Dbuildtype=release" +``` +where the variable `MSMPI_INC` and `MSMPI_LIB64` are required environment +variable for using `MSMPI`. + +Please [raise an issue](https://github.com/yumengch/pyPDAF/issues/new) if you +have any questions or problems with this. diff --git a/pyPDAF/source/docs/source/introduction.md b/pyPDAF/source/docs/source/introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..68c84a164cd29680fc87f07debafa2d120d8ccc9 --- /dev/null +++ b/pyPDAF/source/docs/source/introduction.md @@ -0,0 +1,39 @@ +pyPDAF is a Python interface to the `Parallel Data Assimilation Framwork (PDAF) `_ written in Fortran. +The latest pyPDAF supports PDAF-V3.0. + +As an interface to PDAF, pyPDAF supports all PDAF functionalities. You can use pyPDAF to construct +a parallel ensemble data assimilation system purely in Python. The pyPDAF is designed as a framework +that defines the workflow of given DA algorithms. Considering the versatility of the software, +information on the model and observations are passed to the DA algorithms through user-supplied +functions. With pyPDAF, all user-supplied functions can be implemented in Python. We expect that +the coding of the user-supplied functions will be easier and more flexible than in Fortran due to +the rich Python ecosystem. + +pyPDAF can be used with two modes: + - online mode: DA is performed without interrupting the model program. Here, the model code is + extended by calling PDAF functions to generate a single program. In online mode, + the filtering gets the model state and distributes the analysis to model by in-memory exchange. + This is the recommended mode for better efficiency. + - offline mode: DA is performed after the model program is finished. Here, a separate program + is generated to perform DA. In offline mode, + the filtering reads the model state from disk and writes the analysis to disk. + + +The potential applications of pyPDAF include: + - online DA systems with Python models, e.g., machine-learning models + - offline DA systems + +This is a great tool for researchers who want to test and develop new DA systems. +Compared to Fortran systems, the efficiency is decreased mainly from user-supplied functions +and overhead for array conversions between Fortran and Python. The core DA algorithms are +as efficient as in PDAF. Note that, for computational +intensive user-supplied functions, the efficiency can be improved by using just-in-time compilation +tools such as `numba`. + +To get started, we highly recommend to start from the Jupyter notebook +example for +`a serial ensemble DA system using a simple wave model `_. + +We also provide more structured offline and online examples. One can adapt these examples based on their needs + - `A parallel online ensemble DA system using a simple wave model `_ + - `A parallel offline ensemble DA system using a simple wave model `_ diff --git a/pyPDAF/source/docs/source/links.md b/pyPDAF/source/docs/source/links.md new file mode 100644 index 0000000000000000000000000000000000000000..2204b39350586d5b935808b801334c6a6a7ed34f --- /dev/null +++ b/pyPDAF/source/docs/source/links.md @@ -0,0 +1,13 @@ +# Other useful links + +This documentation is still a work in progress, we can only provide a handful of information. There are some useful information in PDAF documentation that explains +the implementation and options of various aspects of DA algorithms. + +- [Filter options](https://pdaf.awi.de/trac/wiki/AvailableOptionsforInitPDAF) +- [Domain localisation options](https://pdaf.awi.de/trac/wiki/OMI_observation_modules#init_dim_obs_l_OBSTYPE) +- [Observation operators](https://pdaf.awi.de/trac/wiki/OMI_observation_operators#PDAF-OMIObservationOperators) +- [Debug OMI](https://pdaf.awi.de/trac/wiki/OMI_observation_diagnostics_PDAF3) +- [IAU](https://pdaf.awi.de/trac/wiki/IncrementalAnalysisUpdates) +- [PDAFomi additional functionalities](https://pdaf.awi.de/trac/wiki/PDAFomi_additional_functionality#AdditionalFunctionalityofPDAF-OMI) +- [Custom local analysis domain observations](https://pdaf.awi.de/trac/wiki/OMI_search_local_observations) +- [Custom observation operator](https://pdaf.awi.de/trac/wiki/OMI_observation_operators#Implementingyourownobservationoperator) \ No newline at end of file diff --git a/pyPDAF/source/docs/source/naming_convention.md b/pyPDAF/source/docs/source/naming_convention.md new file mode 100644 index 0000000000000000000000000000000000000000..11ebfdbf8be9af0eea5845451436e5bcbf893910 --- /dev/null +++ b/pyPDAF/source/docs/source/naming_convention.md @@ -0,0 +1,29 @@ +# Variable naming conventions + +The suffix of variables in (py)PDAF follows a few naming conventions. +Understanding these suffixes can help us understand the meaning of variables +in user-supplied functions. In this way, one can implement the user-supplied +functions more efficiently. + +`_p` typically means process-local variables. In weather and climate models, to +use multiple CPUs, the computational domain is decomposed into many sub-domains. +Each sub-domain is simulated by one processor. This is called domain decomposition. +The `_p` variables typically means that they only contains information of the +sub-domain. This is relevant for implementing observations. For example, `obs_p` +means observations reside in the region of corresponding sub-domains. If the model +is not parallel, `_p` is simply the global domain. + +`_l` suffix is related to the local domain of domain localisation of ensemble filters. +This is different from the domain decomposition used for model parallelisation. +In domain localisation, each local domain does data assimilation independently. +One local domain typically only assimilates observations within given localisation radius. +Therefore, `_l` suffix corresponds to each local analysis domain. + +`_f` denotes full observations. However, this does not necessarily mean all +observations or global observations. Instead, the meaning of these +variables depends on the `use_global_obs` set by :func:`pyPDAF.PDAFomi.set_use_global_obs`. + - `use_global_obs=0`, + - for filters using domain localisation: `_f` means observations within localisation radius. + - for filters without domain localisation: `_f` means observations in each processor + making it the same as `_p`. + - `use_global_obs=1`, `_f` means all observations globally. diff --git a/pyPDAF/source/docs/source/parallel.md b/pyPDAF/source/docs/source/parallel.md new file mode 100644 index 0000000000000000000000000000000000000000..643f2fde32b010af46b79716191c40438c51ae2f --- /dev/null +++ b/pyPDAF/source/docs/source/parallel.md @@ -0,0 +1,71 @@ + +# Parallelisation Strategy +PDAF can be run both in serial and parallel. +In either cases, Message Parsing Interface (MPI) is used. +In (py)PDAF, users need to specify the MPI communicators for the model (`comm_model`), +the filter(`comm_filter`), and the coupling (`comm_couple`) +between the model and the filter. These communicators are specified when PDAF is initialised +by [`pyPDAF.PDAF.init`](#pyPDAF.init). +In MPI, a communicator is formed by a group of processes. +The default communicator in MPI is called `MPI_COMM_WORLD`. + +If we design a program run by `npes_world = 12` processes, +the default MPI communicator, `MPI_COMM_WORLD`, controls all these processes. +In (py)PDAF, one can make use of all processes, +or only a handful of these processes. +In the former case, the communicator for an ensemble system +is `comm_ens = MPI_COMM_WORLD` with `npes_ens = 12` processes. +In the latter case, one can choose a few processors (`npes_ens`) +as communicator `comm_ens` dedicated to PDAF, and the rest processors +can be used for other tasks, e.g. I/O operations. +The MPI communicator used by (py)PDAF can be set +by [`pyPDAF.PDAF.set_comm_pdaf`](#pyPDAF.PDAF.set_comm_pdaf). + +## Online mode +![Illustration of online PDAF MPI communicators](https://pdaf.awi.de/pics/communicators_PDAFonline.png "PDAF parallel strategy for online DA system") + +*Here is an illustration of the parallel strategy for an online DA system. +The example in this figure uses `npes_ens = 12` with `npes_model = npes_filter = 4` +where the filtering (filter commnicator) is done on one of the model communicators. +The model is decomposed into 4 sub-domains in this figure. Each coupling communicator +collects state vector from each model process running the same model domain.* + +### Model communicator +Here, `comm_ens` can be divided into 3 model communicators (`model_comm`), +each of which has `npes_model = 4` processes. +In the context of PDAF, each model communicator can perform an independent model run. +That is, we have 3 parallel model tasks (`n_modeltasks = 3`). In this specific example, +- if we have 3 ensemble members (`dim_ens = 3`), each model task runs one ensemble member. This is the case in the figure above. This means that the ensemble members local to the model task, `dim_ens_l = 1`. This setup is called `fully flexible` setup in PDAF. +- in the case that `dim_ens > 3`, each model task runs more than one ensemble member serially. Each model task could also have different number of local ensemble members as `dim_ens` is not necessarily a multiple of `n_modeltasks`. For example, if `dim_ens = 4`, one model task runs `dim_ens_l = 2` ensemble members serially and others just runs `dim_ens_l = 1` ensemble member. + +### Filter communicator +In our example, one model task runs on `npes_model = 4` processes. +For the sake of efficiency, most physical climate models perform domain decomposition. +Under the domain decomposition, the model domain is divided into smaller domains, +and each process only simulates a sub-domain. To make the example more concrete, +if the model has 2 variables and 44 grid points, each sub-domain will +simulate 11 grid points. The model domain decomposition fits well with the +concept of domain localisation where the filtering algorithm perform assimilation +for each element of the state vector individually, e.g.: +```python +for element in state_vector: + do_assimilation(element) +``` +The domain localisation is great for parallelisation as the assimilation of each element of the state vector is completely independent of each other. In (py)PDAF, one can follow the domain decomposition of the model. In this case, one of the model communicators can be used as a filter communicator (`comm_filter`) where the number of processes performing filtering is `npes_filter = npes_filter = 4`. In the example above, each local domain contains `dim_p = `{math}`2 \times 11` number of elements in the process-local state vector, `state_p`, where the subscript `p` represents arrays on a specific process, or PE-local. Certainly, this means other model communicators are not in use during the filtering stage, but it is a good compromise compared to the increased complexity of redistributing the state vector. + +### Coupling communicator +In the filtering stage, ensemble systems must gather model state from each ensemble member to the filtering processes. This is done by a coupling communicator (`comm_couple`), where model processors simulating the same sub-domain are grouped together. The number of processes used for coupling is usually `n_modeltasks`. After the filtering, the coupling communicator is used to distribute the analysis back to the model for following simulations. + +## Offline mode +In PDAF, the parallelisation of the offline mode is a simplification of the online mode. In offline mode, the DA program only performs the filtering algorithm. If the filtering is performed in serial, the model, filter and coupling communicator are all given as `comm_ens` with `npes_ens = 1`. + +![Illustration of offline PDAF MPI communicators](https://pdaf.awi.de/pics/communicators_PDAFoffline.png "PDAF parallel strategy for offline DA system") + +*Here is an illustration of the parallel strategy for an offline DA system. The example in this figure uses `npes_ens = 4` with `npes_model = npes_filter = 4`. The model is assumed to be decomposed into 4 sub-domains in this figure.* + +For the filtering algorithm supporting parallelisation, if `npes_ens = 4`, the state vector is partitioned into `npes_model = npes_filter = 4` state vectors that is local to one process, `state_p`, where the subscript `p` represents process-local, or PE-local. This means that each process performs filtering for only a section of the full state vector, and PDAF assumes that the ensemble model is run by `npes_model = 4` number of processes. The reason for this treatment is explained in [Filter communicator setup in online mode](#filter-communicator). In this case, `comm_filter = comm_model = comm_ens`. The coupling communicator is used to collect ensemble from different model tasks to the filter processes in online mode. In the offline mode, the model state is read from disk files, and only one model task is run. Hence, one `comm_couple` corresponds to just one model process. + + + + + diff --git a/pyPDAF/source/docs/source/user_desc/py__add_obs_err_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__add_obs_err_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..9fc3cd727cb0e47df6e890f08f1c06f7f37c21cf --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__add_obs_err_pdaf.rst @@ -0,0 +1,31 @@ +py__add_obs_err_pdaf +==================== + +.. py:function:: py__add_obs_err_pdaf(step: int, dim_obs_p: int, c_p: np.ndarray) -> np.ndarray + + Add the observation error covariance matrix to the matrix :math:`\mathbf{C}_p`. + + The input matrix is the projection of the ensemble covariance + matrix onto the observation space that is computed during the + analysis step of the stochastic EnKF, i.e. :math:`HPH^T`. + The function returns :math:`HPH^T + R`. + + The operation is for the global observation space, thus it is + independent of whether the filter is executed with or without + parallelization. + + Parameters + ---------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + C_p : ndarray[np.float64, ndim=2] + Matrix to which the observation error covariance matrix is added + shape: (dim_obs_p, dim_obs_p) + + Returns + ------- + C_p : ndarray[np.float64, ndim=2] + Matrix with added obs error covariance, i.e., HPH.T + R + shape: (dim_obs_p, dim_obs_p) \ No newline at end of file diff --git a/pyPDAF/source/docs/source/user_desc/py__collect_state_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__collect_state_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..e652f1a31630c0596dd89d0f2d27700755f33d64 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__collect_state_pdaf.rst @@ -0,0 +1,19 @@ +py__collect_state_pdaf +====================== + +.. py:function:: py__collect_state_pdaf(dim_p: int, state_p: np.ndarray) -> np.ndarray + + Collect state vector from model/any arrays to pdaf arrays + + Parameters + ---------- + dim_p : int + pe-local state dimension + + state_p : ndarray[tuple[dim_p, ...], np.float64] + local state vector + + Returns + ------- + state_p : ndarray[tuple[dim_p, ...], np.float64] + local state vector diff --git a/pyPDAF/source/docs/source/user_desc/py__cvt_adj_ens_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__cvt_adj_ens_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..fa8730606993a37224c1ddd0be0d8955f0f5fc29 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__cvt_adj_ens_pdaf.rst @@ -0,0 +1,39 @@ +py__cvt_adj_ens_pdaf +===================== + +.. py:function:: py__cvt_adj_ens_pdaf(iter: int, dim_p: int, dim_ens: int, dim_cv_ens_p:int, ens: np.ndarray, vcv_p: np.ndarray, cv_p: np.ndarray) -> np.ndarray: + + The adjoint control variable transformation involving ensembles. + + Here, this function performs + :math:`\mathbf{U}^\mathrm{T} \mathbf{v}_h`. Here, the input vector can be + :math:`\mathbf{v}_h = \mathbf{H}^\mathrm{T}\mathbf{R}^{-1}\delta \mathbf{x}` + with :math:`\delta \mathbf{x}` the innovation vector. + + The control vector transform is given by :math:`\mathbf{U}\mathbf{v}` with + :math:`\mathbf{v}` the control vector and :math:`\mathbf{U}` the transformation + matrix, which can be :math:`\mathbf{B}^\frac{1}{2}`. + + This function is used in 3DEnVar and hybrid 3DVar. + + Parameters + ---------- + iter: int + Current optimisation iteration number. + dim_p: int + Dimension of the state vector. + dim_ens: int + Dimension of the ensemble. + dim_cv_ens_p: int + Dimension of the control vector. + ens_p: np.ndarray[np.float, dim=2] + Ensemble matrix. shape: (dim_p, dim_ens) + vcv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{v}_h`. shape: (dim_p, ) + cv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U}^\mathrm{T} \mathbf{v}_h`. shape: (dim_cv_ens_p, ) + + Returns + ------- + cv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U}^\mathrm{T} \mathbf{v}_h`. shape: (dim_cv_ens_p, ) diff --git a/pyPDAF/source/docs/source/user_desc/py__cvt_adj_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__cvt_adj_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..7f9580f19f30ed4cf9dc46643751209f249e3a27 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__cvt_adj_pdaf.rst @@ -0,0 +1,35 @@ +py__cvt_adj_pdaf +================ + +.. py:function:: py__cvt_adj_pdaf(iter: int, dim_p: int, dim_cvec: int, vcv_p: np.ndarray, cv_p: np.ndarray) -> np.ndarray + + The adjoint control variable transformation. + + Here, this function performs + :math:`\mathbf{U}^\mathrm{T} \mathbf{v}_h`. Here, the input vector can be + :math:`\mathbf{v}_h = \mathbf{H}^\mathrm{T}\mathbf{R}^{-1}\delta \mathbf{x}` + with :math:`\delta \mathbf{x}` the innovation vector. + + The control vector transform is given by :math:`\mathbf{U}\mathbf{v}` with + :math:`\mathbf{v}` the control vector and :math:`\mathbf{U}` the transformation + matrix, which can be :math:`\mathbf{B}^\frac{1}{2}`. + + This function is used in 3DVar and hybrid 3DVar. + + Parameters + ---------- + iter: int + Current optimisation iteration number. + dim_p: int + Dimension of the state vector. + dim_cvec: int + Dimension of the control vector. + vcv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{v}_h`. shape: (dim_p, ) + cv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U}^\mathrm{T} \mathbf{v}_h`. shape: (dim_cvec, ) + + Returns + ------- + cv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U}^\mathrm{T} \mathbf{v}_h`. shape: (dim_cvec, ) diff --git a/pyPDAF/source/docs/source/user_desc/py__cvt_ens_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__cvt_ens_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..b2f441db5c1c65bbe8fb60354f48d056c340f116 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__cvt_ens_pdaf.rst @@ -0,0 +1,34 @@ +py__cvt_ens_pdaf +================ + +.. py:function:: py__cvt_ens_pdaf(iter: int, dim_p: int, dim_ens: int, dim_cv_ens_p: int, v_p: np.ndarray, vv_p: np.ndarray) -> np.ndarray + + The control variable transformation involving ensembles. + + Here, this function performs :math:`\mathbf{U} \mathbf{v}` with + :math:`\mathbf{v}` the control vector and :math:`\mathbf{U}` the transformation + matrix, which can be :math:`\mathbf{B}^\frac{1}{2}`. + + This function is used in 3DEnVar and hybrid 3DVar. + + Parameters + ---------- + iter: int + Current optimisation iteration number. + dim_p: int + Dimension of the state vector. + dim_ens: int + Dimension of the ensemble. + dim_cv_ens_p: int + Dimension of the control vector. + ens_p: np.ndarray[np.float, dim=2] + Ensemble matrix. shape: (dim_p, dim_ens) + v_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{v}`. shape: (dim_cv_ens_p, ) + vv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U} \mathbf{v}`. shape: (dim_p, ) + + Returns + ------- + vv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U} \mathbf{v}`. shape: (dim_p, ) diff --git a/pyPDAF/source/docs/source/user_desc/py__cvt_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__cvt_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..a8bb03bb939dd56182bea1f444ab1a9f397eb8d3 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__cvt_pdaf.rst @@ -0,0 +1,30 @@ +py__cvt_pdaf +============ + +.. py:function:: py__cvt_pdaf(iter: int, dim_p: int, dim_cvec: int, cv_p: np.ndarray, vv_p: np.ndarray) -> np.ndarray + + The control variable transformation. + + Here, this function performs :math:`\mathbf{U} \mathbf{v}` with + :math:`\mathbf{v}` the control vector and :math:`\mathbf{U}` the transformation + matrix, which can be :math:`\mathbf{B}^\frac{1}{2}`. + + This function is used in 3DVar and hybrid 3DVar. + + Parameters + ---------- + iter: int + Current optimisation iteration number. + dim_p: int + Dimension of the state vector. + dim_cvec: int + Dimension of the control vector. + cv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{v}`. shape: (dim_cvec, ) + vv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U} \mathbf{v}`. shape: (dim_p, ) + + Returns + ------- + vv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U} \mathbf{v}`. shape: (dim_p, ) diff --git a/pyPDAF/source/docs/source/user_desc/py__distribute_state_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__distribute_state_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..9db388eeb79d170fef1008cdbae4f6cae2fe03ed --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__distribute_state_pdaf.rst @@ -0,0 +1,20 @@ +py__distribute_state_pdaf +========================= + +.. py:function:: py__distribute_state_pdaf(dim_p: int, state_p: np.ndarray) -> np.ndarray + + Distribute a state vector from pdaf to the model/any arrays + + Parameters + ---------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) \ No newline at end of file diff --git a/pyPDAF/source/docs/source/user_desc/py__g2l_obs_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__g2l_obs_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..7d327088c968bd21976c2178424e78008efac663 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__g2l_obs_pdaf.rst @@ -0,0 +1,29 @@ +py__g2l_obs_pdaf +================ + +.. py:function:: py__g2l_obs_pdaf(domain_p: int, step: int, dim_obs_f: int, dim_obs_l: int, mstate_f: np.ndarray, mstate_l: np.ndarray) -> np.ndarray + + Convert global observed state vector to local vector. + + This is used by domain localisation methods. In these methods, each local + domain has their own observation vector and observed state vector. + + Parameters + ---------- + domain_p:int + Current local domain index + step: int + Current time step + dim_obs_f: int + Global observation vector dimension. + dim_obs_l: int + Local observation vector dimension. + mstate_f: np.ndarray[np.float64, dim=1] + Global observed state vector. shape: (dim_obs_f,) + mstate_l: np.ndarray[np.float64, dim=1] + Local observed state vector. shape: (dim_obs_l,) + + Returns + ------- + mstate_l: np.ndarray[np.float64, dim=1] + Local observed state vector. shape: (dim_obs_l,) diff --git a/pyPDAF/source/docs/source/user_desc/py__g2l_state_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__g2l_state_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..ba64cfda42bbb9382d461a6b724a323a487c5002 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__g2l_state_pdaf.rst @@ -0,0 +1,28 @@ +py__g2l_state_pdaf +================== + +.. py:function:: py__g2l_state_pdaf(step: int, domain_p: int, dim_p: int, state_p: np.ndarray, dim_l: int, state_l: np.ndarray) -> np.ndarray + + Get local state vector. + + Get the state vector for analysis local domain. + + Parameters + ---------- + step: int + Current time step + domain_p: int + Current local domain index + dim_p: int + Process-local state vector dimension. + state_p: np.ndarray[np.float, dim=1] + Process-local state vector. + dim_l: int + Local analysis domain state vector dimension. + state_l: np.ndarray[np.float, dim=1] + Local analysis domain state vector. Shape: (dim_l,) + + Returns + ------- + state_l: np.ndarray[np.float, dim=1] + Local analysis domain state vector. Shape: (dim_l,) diff --git a/pyPDAF/source/docs/source/user_desc/py__get_obs_f_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__get_obs_f_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..168002e31f0eb06f0eb85d65b1a714fa1e4a5140 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__get_obs_f_pdaf.rst @@ -0,0 +1,23 @@ +py__get_obs_f_pdaf +================== + +.. py:function:: py__get_obs_f_pdaf(step: int, dim_obs_f: int, observation_f: np.ndarray) -> np.ndarray + + Receive synthetic observations from PDAF. + + This function is used in twin experiments for observation generations. + One can, for example, save synthetic observations in this function. + + Parameters + ---------- + step: int + Current time step + dim_obs_f: int + Full observation vector dimension. + observation_f: np.ndarray[np.float, dim=1] + Full observation vector. + + Returns + ------- + observation_f: np.ndarray[np.float, dim=1] + Full observation vector. diff --git a/pyPDAF/source/docs/source/user_desc/py__init_dim_l_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__init_dim_l_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..831b32c4a9bd39aa1ffc27954566e627c8037dad --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__init_dim_l_pdaf.rst @@ -0,0 +1,22 @@ +py__init_dim_l_pdaf +=================== + +.. py:function:: py__init_dim_l_pdaf(step: int, domain_p: int, dim_l: int) -> int + + Initialise local analysis domain state vector dimension. + + When PDAFlocal is used, one should call :func:`pyPDAF.PDAFlocal.set_indices` here. + + Parameters + ---------- + step: int + Current step + domain_p: int + Current local domain index + dim_l: int + Local analysis domain state vector dimension. + + Returns + ------- + dim_l: int + Local analysis domain state vector dimension. diff --git a/pyPDAF/source/docs/source/user_desc/py__init_dim_obs_f_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__init_dim_obs_f_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..456819afadc29be59935fd20f28feb58cfb35263 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__init_dim_obs_f_pdaf.rst @@ -0,0 +1,23 @@ +py__init_dim_obs_f_pdaf +======================= + +.. py:function:: py__init_dim_obs_f_pdaf(step: int, dim_obs_f: int) -> int + + Determine the size of the full observations vector + + This function is used with domain localised filters to obtain the dimension of full + observation vector that contains observations outside process-local domains. + The smallest vector only needs observations within localisation radius of the + process-local domain. + + Parameters + ---------- + step : int + Current time step. + dim_obs_f : int + Dimension of the full observation vector. + + Returns + ------- + dim_obs_f : int + Dimension of the full observation vector. diff --git a/pyPDAF/source/docs/source/user_desc/py__init_dim_obs_l_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__init_dim_obs_l_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..7257178c8964923129985625236468897f40211e --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__init_dim_obs_l_pdaf.rst @@ -0,0 +1,24 @@ +py__init_dim_obs_l_pdaf +======================= + +.. py:function:: py__init_dim_obs_l_pdaf(domain_p: int, step: int, dim_obs_f: int, dim_obs_l: int) -> int + + Initialise the dimension of local analysis domain observation vector. + + One can simplify this function by using :func:`pyPDAF.PDAFomi.init_dim_obs_l_xxx`. + + Parameters + ---------- + domain_p: int + Current local domain index + step: int + Current step + dim_obs_f: int + Global observation vector dimension. + dim_obs_l: int + Local observation vector dimension. + + Returns + ------- + dim_obs_l: int + Local observation vector dimension. diff --git a/pyPDAF/source/docs/source/user_desc/py__init_dim_obs_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__init_dim_obs_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..3b107eb577b8508f6835b24f78ff7f7d83ee49b4 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__init_dim_obs_pdaf.rst @@ -0,0 +1,30 @@ +py__init_dim_obs_pdaf +===================== + +.. py:function:: py__init_dim_obs_pdaf(step: int, dim_obs_p: int) -> int + + Determine the size of the vector of observations + + The primary purpose of this function is to + obtain the dimension of the observation vector. + In OMI, in this function, one also sets the properties + of `obs_f`, read the observation vector from + files, setting the observation error variance + when diagonal observation error covariance matrix + is used. The `pyPDAF.PDAF.omi_gather_obs` function + is also called here. + + Furthermore, in this user-supplied function, one also sets the interpolation + coefficients used by observation operators. + + Parameters + ---------- + step : int + Current time step. + dim_obs_p : int + Dimension of the observation vector. + + Returns + ------- + dim_obs_p : int + Dimension of the observation vector. diff --git a/pyPDAF/source/docs/source/user_desc/py__init_ens_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__init_ens_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..f763f439655b53c2ffad6bf780882d0464dac6d4 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__init_ens_pdaf.rst @@ -0,0 +1,79 @@ +py__init_ens_pdaf +================= + +.. py:function:: py__init_ens_pdaf(filtertype: int, dim_p: int, dim_ens: int, state_p: np.ndarray, uinv: np.ndarray, ens_p: np.ndarray, flag: int) -> Tuple[np.ndarray, np.ndarray, np.ndarray, int] + + Fill the ensemble array that is provided by PDAF with an initial ensemble of model states. + + This function is called by :func:`pyPDAF.PDAF.init`. The initialised + ensemble array will be distributed to model by :func:`pyPDAF.PDAF.init_forecast`. + + Parameters + ---------- + filtertype : int + filter type given in PDAF_init + dim_p : int + PE-local state dimension given by PDAF_init + dim_ens : int + number of ensemble members + state_p : ndarray[np.float64, ndim=1] + PE-local model state + This array must be filled with the initial + state of the model for SEEK, but it is not + used for ensemble-based filters. + One can still make use of this array within + this function. + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + This array is the inverse of matrix + formed by right singular vectors of error + covariance matrix of ensemble perturbations. + This array has to be filled in SEEK, but it is + not used for ensemble-based filters. + Nevertheless, one can still make use of this + array within this function e.g., + for generating an initial ensemble perturbation + from a given covariance matrix. + Dimension of this array is determined by the + filter type. + * (dim_ens, dim_ens) for (L)ETKF, (L)NETF, (L)KNETF, and SEEK + * (dim_ens - 1, dim_ens - 1) for (L)SEIK, (L)ESTKF, and 3DVar using ensemble + * (1, 1) for (L)EnKF, particle filters and gen_obs + Array shape: (dim_ens - 1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + This array must be filled with the initial + state of the model for SEEK, but it is not + used for ensemble-based filters. + One can still make use of this array within + this function. + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + This array is the inverse of matrix + formed by right singular vectors of error + covariance matrix of ensemble perturbations. + This array has to be filled in SEEK, but it is + not used for ensemble-based filters. + Nevertheless, one can still make use of this + array within this function e.g., + for generating an initial ensemble perturbation + from a given covariance matrix. + Dimension of this array is determined by the + filter type. + * (dim_ens, dim_ens) for (L)ETKF, (L)NETF, (L)KNETF, and SEEK + * (dim_ens - 1, dim_ens - 1) for (L)SEIK, (L)ESTKF, and 3DVar using ensemble + * (1, 1) for (L)EnKF, particle filters and gen_obs + Array shape: (dim_ens - 1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag diff --git a/pyPDAF/source/docs/source/user_desc/py__init_n_domains_p_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__init_n_domains_p_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..d5a45850573cab6f19471e888edba6785a1282a3 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__init_n_domains_p_pdaf.rst @@ -0,0 +1,18 @@ +py__init_n_domains_p_pdaf +========================= + +.. py:function:: py__init_n_domains_p_pdaf(step: int, n_domains_p: int) -> int + + Get number of analysis domains. + + Parameters + ---------- + step: int + Current step + n_domains_p: int + Number of analysis domains. + + Returns + ------- + n_domains_p: int + Number of analysis domains. diff --git a/pyPDAF/source/docs/source/user_desc/py__init_obs_covar_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__init_obs_covar_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..2b0bc79167904339d02c2b57d5e4aa6559e59788 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__init_obs_covar_pdaf.rst @@ -0,0 +1,30 @@ +py__init_obs_covar_pdaf +======================= + +.. py:function:: py__init_obs_covar_pdaf(step: int, dim_obs: int, dim_obs_p: int, covar: np.ndarray, obs_p: np.ndarray, isdiag: bool) -> Tuple[np.ndarray, bool] + + Provide observation error covariance matrix to PDAF. + + This function is used in stochastic EnKF for generating observation perturbations. + + Parameters + ---------- + step: int + current time step + dim_obs : int + dimension of global observation vector + dim_obs_p: int + dimension of process-local observation vector + covar: np.ndarray[np.float64, dim=2] + Observation error covariance matrix. shape: (dim_obs_p, dim_obs_p) + obs_p: np.ndarray[np.float64, dim=1] + Process-local observation vector. shape: dim_obs_p + isdiag: bool + Flag indicating if the covariance matrix is diagonal. + + Returns + ------- + covar: np.ndarray[np.float64, dim=2] + Observation error covariance matrix. shape: (dim_obs_p, dim_obs_p) + is_diag: bool + Flag indicating if the covariance matrix is diagonal. diff --git a/pyPDAF/source/docs/source/user_desc/py__init_obs_f_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__init_obs_f_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..e898c483383b4c5590ee2d78f779b908ae07c4a2 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__init_obs_f_pdaf.rst @@ -0,0 +1,25 @@ +py__init_obs_f_pdaf +=================== + +.. py:function:: py__init_obs_f_pdaf(step: int, dim_obs_f: int, observation_f: np.ndarray) -> np.ndarray + + Provide the observation vector for the current time step. + + This function is used with domain localised filters to obtain a full + observation vector that contains observations outside process-local domains. + The smallest vector only needs observations within localisation radius of the + process-local domain. + + Parameters + ---------- + step : int + Current time step. + dim_obs_f : int + Dimension of the observation vector. + observation_f : ndarray[np.float64, ndim=1] + Observation vector. + + Returns + ------- + observation_f : ndarray[np.float64, ndim=1] + Filled observation vector. diff --git a/pyPDAF/source/docs/source/user_desc/py__init_obs_l_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__init_obs_l_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..33cc6a42b32b853b22e22ff0f96c66350ec5aa13 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__init_obs_l_pdaf.rst @@ -0,0 +1,22 @@ +py__init_obs_l_pdaf +=================== + +.. py:function:: py__init_obs_l_pdaf(domain_p: int, step: int, dim_obs_l: int, observation_l: np.ndarray) -> np.ndarray + + Initialise observation vector for local analysis domain. + + Parameters + ---------- + domain_p: int + Current local domain index + step: int + Current time step + dim_obs_l: int + Local observation vector dimension. + observation_l: np.ndarray[np.float, dim=1] + Local observation vector. + + Returns + ------- + observation_l: np.ndarray[np.float, dim=1] + Local observation vector. diff --git a/pyPDAF/source/docs/source/user_desc/py__init_obs_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__init_obs_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..a4b3b9f4f6d0cc7bc8dc0ac31aae9ff519dfff37 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__init_obs_pdaf.rst @@ -0,0 +1,20 @@ +py__init_obs_pdaf +================= + +.. py:function:: py__init_obs_pdaf(step: int, dim_obs_p: int, observation_p: np.ndarray) -> np.ndarray + + Provide the observation vector for the current time step. + + Parameters + ---------- + step : int + Current time step. + dim_obs_p : int + Dimension of the observation vector. + observation_p : ndarray[np.float64, ndim=1] + Observation vector. + + Returns + ------- + observation_p : ndarray[np.float64, ndim=1] + Filled observation vector. \ No newline at end of file diff --git a/pyPDAF/source/docs/source/user_desc/py__init_obserr_f_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__init_obserr_f_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..92c0844a635257f2110be8eab2b5f8dd87b18123 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__init_obserr_f_pdaf.rst @@ -0,0 +1,22 @@ +py__init_obserr_f_pdaf +====================== + +.. py:function:: py__init_obserr_f_pdaf(step: int, dim_obs_f: int, obs_f: np.ndarray, obserr_f: np.ndarray) -> np.ndarray + + Initializes the full vector of observations error standard deviations. + + Parameters + ---------- + step : int + Current time step. + dim_obs_f : int + Full observation vector dimension. + obs_f : np.ndarray[np.float, dim=1] + Full observation vector. + obserr_f : np.ndarray[np.float, dim=1] + Full observation error vector. + + Returns + ------- + obserr_f : np.ndarray[np.float, dim=1] + Full observation error vector. diff --git a/pyPDAF/source/docs/source/user_desc/py__init_obsvar_l_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__init_obsvar_l_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..d39e07089f85745799c749188ab4839505141397 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__init_obsvar_l_pdaf.rst @@ -0,0 +1,28 @@ +py__init_obsvar_l_pdaf +======================= + +.. py:function:: py__init_obsvar_l_pdaf(domain_p: int, step: int, dim_obs_l: int, obs_l: np.ndarray, dim_obs_p: int, meanvar_l: float) -> float + + Get mean of analysis domain local observation variance. + + This is used by local adaptive forgetting factor (type_forget=2) + + Parameters + ---------- + domain_p: int + Current local domain index + step: int + Current time step + dim_obs_l: int + Local observation vector dimension. + obs_l: np.ndarray[np.float, dim=1] + Local observation vector. + dim_obs_p: int + Process-local observation vector dimension. + meanvar_l: float + Mean of analysis domain local observation variance. + + Returns + ------- + meanvar_l: float + Mean of analysis domain local observation variance. diff --git a/pyPDAF/source/docs/source/user_desc/py__init_obsvar_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__init_obsvar_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..ea05fab5f2a4cecd533e74f8da29ea7950ba24f7 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__init_obsvar_pdaf.rst @@ -0,0 +1,25 @@ +py__init_obsvar_pdaf +====================== + +.. py:function:: py__init_obsvar_pdaf(step: int, dim_obs_p: int, obs_p: np.ndarray, meanvar: float) -> float + + Compute mean observation error variance. + + This is used by ETKF-variants for adaptive forgetting factor (type_forget=1). + This can be global mean, or sub-domain mean. + + Parameters + ---------- + step: int + Current time step + dim_obs_p: int + Dimension of process-local observation vector + obs_p: np.ndarray[np.float64, dim=1] + Process-local observation vector. shape: (dim_obs_p,) + meanvar: float + Mean observation error variance. + + Returns + ------- + meanvar: float + Mean observation error variance. diff --git a/pyPDAF/source/docs/source/user_desc/py__init_obsvars_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__init_obsvars_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..33578930667d8c3f63344751678a94579012f391 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__init_obsvars_pdaf.rst @@ -0,0 +1,22 @@ +py__init_obsvars_pdaf +======================= + +.. py:function:: py__init_obsvars_pdaf(step: int, dim_obs_f: int, var_f: np.ndarray) -> np.ndarray + + Provide a vector observation variance. + + This is used by EnSRF/EAKF. + + Parameters + ---------- + step: int + Current time step + dim_obs_f: int + Dimension of observation vector + var_f: np.ndarray[np.float64, dim=1] + Observation variance vector. shape: (dim_obs_f,) + + Returns + ------- + var_f: np.ndarray[np.float64, dim=1] + Observation variance vector. shape: (dim_obs_f,) diff --git a/pyPDAF/source/docs/source/user_desc/py__l2g_state_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__l2g_state_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..b107d9022b904ebf7680331f95fc4762b6b94361 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__l2g_state_pdaf.rst @@ -0,0 +1,26 @@ +py__l2g_state_pdaf +================== + +.. py:function:: py__l2g_state_pdaf(step: int, domain_p: int, dim_l: int, state_l: np.ndarray, dim_p: int, state_p: np.ndarray) -> np.ndarray + + Assign local state vector to process-local global state vector. + + Parameters + ---------- + step: int + Current time step + domain_p: int + Current local domain index + dim_l: int + Local analysis domain state vector dimension. + state_l: np.ndarray[np.float, dim=1] + Local analysis domain state vector. + dim_p: int + Process-local global state vector dimension. + state_p: np.ndarray[np.float, dim=1] + Process-local global state vector. + + Returns + ------- + state_p: np.ndarray[np.float, dim=1] + Process-local global state vector. diff --git a/pyPDAF/source/docs/source/user_desc/py__likelihood_hyb_l_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__likelihood_hyb_l_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..e147aa3526c18dcb89709e9eacc9e89e8748cc45 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__likelihood_hyb_l_pdaf.rst @@ -0,0 +1,44 @@ +py__likelihood_hyb_l_pdaf +========================= + +.. py:function:: py__likelihood_hyb_l_pdaf(domain_p: int, step: int, dim_obs_l: int, obs_l: np.ndarray, gamma: float, resid_l: np.ndarray, likely_l: np.ndarray) -> float + + Compute the likelihood of the observation for a given ensemble member + according to the observations used for the local analysis with hybrid weight. + + The function is used in the localized nonlinear filter LKNETF. The likelihood + depends on the assumed observation error distribution. + For a Gaussian observation error, the likelihood is + :math:`\exp(-0.5(\mathbf{y}-\mathbf{H}\mathbf{x})^\mathrm{T}R^{-1}(\mathbf{y}-\mathbf{H}\mathbf{x}))`. + The vector :math:`\mathbf{y}-\mathbf{H}\mathbf{x} = \mathrm{resid}` is + provided as an input argument. + + The hybrid weight `gamma` is used weight between LNETF and LETKF. which is applied + to :math:`R^{-1}(\mathbf{y}-\mathbf{H}\mathbf{x})`. + + This function is also the place to perform observation localisation. + To initialize a vector of weights, the routine :func:`pyPDAF.PDAF.local_weight` + can be called. + + Parameters + ---------- + domain_p: int + Current local analysis domain index + step: int + Current time step + dim_obs_l: int + Dimension of the local observation vector. + obs_l: np.ndarray[np.float, dim=1] + Observation vector. Shape: (dim_obs_l) + gamma: float + Hybrid weight provided by PDAF + resid_l: np.ndarray[np.float, dim=1] + Residual vector between observations and state. Shape: (dim_obs_l) + likely_l: float + Likelihood of the local observation + + Returns + ------- + likely_l: float + Likelihood of the local observation + diff --git a/pyPDAF/source/docs/source/user_desc/py__likelihood_l_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__likelihood_l_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..08002d21c194be9ff2ed4346d28ea1ad3e4e45af --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__likelihood_l_pdaf.rst @@ -0,0 +1,38 @@ +py__likelihood_l_pdaf +======================= + +.. py:function:: py__likelihood_l_pdaf(domain_p: int, step: int, dim_obs_l: int, obs_l: np.ndarray, resid_l: np.ndarray, likely_l: float) -> float + + Compute the likelihood of the observation for a given ensemble member + according to the observations used for the local analysis. + + The function is used in the localized nonlinear filter LNETF. The likelihood + depends on the assumed observation error distribution. + For a Gaussian observation error, the likelihood is + :math:`\exp(-0.5(\mathbf{y}-\mathbf{H}\mathbf{x})^\mathrm{T}R^{-1}(\mathbf{y}-\mathbf{H}\mathbf{x}))`. + The vector :math:`\mathbf{y}-\mathbf{H}\mathbf{x} = \mathrm{resid}` is + provided as an input argument. + + This function is also the place to perform observation localisation. + To initialize a vector of weights, the routine :func:`pyPDAF.PDAF.local_weight` + can be called. + + Parameters + ---------- + domain_p: int + Current local analysis domain index + step: int + Current time step + dim_obs_l: int + Dimension of the local observation vector. + obs_l: np.ndarray[np.float, dim=1] + Observation vector. Shape: (dim_obs_l) + resid_l: np.ndarray[np.float, dim=1] + Residual vector between observations and state. Shape: (dim_obs_l) + likely_l: float + Likelihood of the local observation + + Returns + ------- + likely_l: float + Likelihood of the local observation diff --git a/pyPDAF/source/docs/source/user_desc/py__likelihood_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__likelihood_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..086e1fda5cb1628be26f3e2f49d660f90c46fe15 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__likelihood_pdaf.rst @@ -0,0 +1,31 @@ +py__likelihood_pdaf +=================== + +.. py:function:: py__likelihood_pdaf(step: int, dim_obs_p: int, obs_p: np.ndarray, resid: np.ndarray, likely: float) -> float + + Compute the likelihood of the observation for a given ensemble member. + + The function is used with the nonlinear filter NETF and particle filter. The likelihood + depends on the assumed observation error distribution. + For a Gaussian observation error, the likelihood is + :math:`\exp(-0.5(\mathbf{y}-\mathbf{H}\mathbf{x})^\mathrm{T}R^{-1}(\mathbf{y}-\mathbf{H}\mathbf{x}))`. + The vector :math:`\mathbf{y}-\mathbf{H}\mathbf{x} = \mathrm{resid}` is + provided as an input argument. + + Parameters + ---------- + step: int + Current time step + dim_obs_p : int + Dimension of the observation vector. + obs_p: np.ndarray[np.float, dim=1] + Observation vector. Shape: (dim_obs_p) + resid: np.ndarray[np.float, dim=1] + Residual vector between observations and state. Shape: (dim_obs_p) + likely: float + Likelihood of the observation + + Returns + ------- + likely: float + Likelihood of the observation diff --git a/pyPDAF/source/docs/source/user_desc/py__localize_covar_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__localize_covar_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..61c38a5c60b527824be872a383046dca46e354b0 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__localize_covar_pdaf.rst @@ -0,0 +1,30 @@ +py__localize_covar_pdaf +======================== + +.. py:function:: py__localize_covar_pdaf(dim_p: int, dim_obs: int, hp_p: np.ndarray, hph: np.ndarray) -> Tuple[np.ndarray, np.ndarray] + + Perform covariance localisation. + + This is only used for stochastic EnKF. The localisation is performed + for HP and HPH.T. + + This can be helped by function :func:`pyPDAF.PDAFomi.localize_covar`. + This is replaced by :func:`PDAFomi.set_localize_covar` in PDAF3. + + Parameters + ---------- + dim_p: int + Dimension of the state vector. + dim_obs: int + Dimension of the observation vector. + hp_p: np.ndarray[np.float, dim=2] + Matrix HP. Shape: (dim_obs, dim_p) + hph: np.ndarray[np.float, dim=2] + Matrix HPH.T. Shape: (dim_obs, dim_obs) + + Returns + ------- + hp_p: np.ndarray[np.float, dim=2] + Localised matrix HP. Shape: (dim_obs, dim_p) + hph: np.ndarray[np.float, dim=2] + Localised matrix HPH.T. Shape: (dim_obs, dim_obs) diff --git a/pyPDAF/source/docs/source/user_desc/py__localize_covar_serial_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__localize_covar_serial_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..398c0122ae6ae03a8590da503b00ae5aacc72bb5 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__localize_covar_serial_pdaf.rst @@ -0,0 +1,29 @@ +py__localize_covar_serial_pdaf +============================== + +.. py:function:: py__localize_covar_serial_pdaf(iobs: int, dim_p: int, dim_obs:int, hp_p: np.ndarray, hxy_p: np.ndarray) -> Tuple[np.ndarray, np.ndarray] + + Apply covariance localisation in EnSRF/EAKF. + + The localisation is applied to each observation element. The weight can be + obtained by :func:`pyPDAF.PDAF.local_weight`. + + Parameters + ---------- + iobs: int + Index of the observation element. + dim_p: int + Dimension of the state vector. + dim_obs: int + Dimension of the observation vector. + hp_p: np.ndarray[np.float, dim=1] + Matrix HP. Shape: (dim_p) + hxy_p: np.ndarray[np.float, dim=1] + Matrix HX (observed state). Shape: (dim_obs) + + Returns + ------- + hp_p: np.ndarray[np.float, dim=1] + Localised matrix HP. Shape: (dim_p) + hxy_p: np.ndarray[np.float, dim=1] + Localised matrix HX (observed state). Shape: (dim_obs) diff --git a/pyPDAF/source/docs/source/user_desc/py__next_observation_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__next_observation_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..e2023c83e64d198518e6c1227af526c8f4d8f6bc --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__next_observation_pdaf.rst @@ -0,0 +1,28 @@ +py__next_observation_pdaf +========================= + +.. py:function:: py__next_observation_pdaf(stepnow: int, nsteps: int, doexit: int, time: float) -> Tuple[int, int, float] + + Get the number of time steps to be computed in the forecast phase. + + At the beginning of a forecast phase, this is called once by + * :func:`pyPDAF.PDAF.init_forecast` + * :func:`pyPDAF.PDAF3.assimilate_X` + * ... + + Parameters + ---------- + stepnow : int + the current time step given by PDAF + + Returns + ------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time diff --git a/pyPDAF/source/docs/source/user_desc/py__obs_op_adj_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__obs_op_adj_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..22f6e0da625513c22d74f4147425a8bfd3ce9367 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__obs_op_adj_pdaf.rst @@ -0,0 +1,28 @@ +py__obs_op_adj_pdaf +==================== + +.. py:function:: py__obs_op_adj_pdaf(step: int, dim_p: int, dim_obs_p: int, m_state_p: np.ndarray, state_p: np.ndarray) -> np.ndarray + + Apply adjoint observation operator + + This function computes :math:`\mathbf{H}^\mathrm{T} \mathbf{w}`, where + :math:`\mathbf{H}` is the observation operator and + :math:`\mathbf{w}` is a vector in observation space. + + Parameters + ---------- + step : int + Current step + dim_p : int + Dimension of state vector + dim_obs_p: int + Dimension of observation vector + m_state_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{w}`. shape: (dim_obs_p,) + state_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{H}^\mathrm{T} \mathbf{w}`. shape: (dim_p,) + + Returns + ------- + state_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{H}^\mathrm{T} \mathbf{w}`. shape: (dim_p,) diff --git a/pyPDAF/source/docs/source/user_desc/py__obs_op_f_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__obs_op_f_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..b9b839ae29e0f5046bfed98fc6adf97bcee6a162 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__obs_op_f_pdaf.rst @@ -0,0 +1,30 @@ +py__obs_op_f_pdaf +=================== + +.. py:function:: py__obs_op_f_pdaf(step: int, dim_p: int, dim_obs_p: int, state_p: np.ndarray, m_state_p: np.ndarray) -> np.ndarray + + Apply observation operator for full observed state vector + + This function computes :math:`\mathbf{H} \mathbf{x}`, where + :math:`\mathbf{H}` is the observation operator and + :math:`\mathbf{x}` is state vector. + See `here `_ + for the meaning of full observations. + + Parameters + ---------- + step : int + Current step + dim_p : int + Dimension of state vector + dim_obs_p: int + Dimension of observation vector + state_p: np.ndarray[np.float, dim=1] + State vector. shape: (dim_p,) + m_state_p: np.ndarray[np.float, dim=1] + Observed state vector. shape: (dim_obs_p,) + + Returns + ------- + m_state_p: np.ndarray[np.float64, dim=1] + Observed state vector. shape: (dim_obs_p,) diff --git a/pyPDAF/source/docs/source/user_desc/py__obs_op_lin_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__obs_op_lin_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..8daca27ba7658de916cdfac2526d496906a001c8 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__obs_op_lin_pdaf.rst @@ -0,0 +1,28 @@ +py__obs_op_lin_pdaf +==================== + +.. py:function:: py__obs_op_lin_pdaf(step: int, dim_p: int, dim_obs_p: int, state_p: np.ndarray, m_state_p: np.ndarray) -> np.ndarray + + Apply linearised observation operator + + This function computes :math:`\mathbf{H} \mathbf{x}`, where + :math:`\mathbf{H}` is the linearised observation operator and + :math:`\mathbf{x}` is state vector. + + Parameters + ---------- + step : int + Current step + dim_p : int + Dimension of state vector + dim_obs_p: int + Dimension of observation vector + state_p: np.ndarray[np.float, dim=1] + State vector. shape: (dim_p,) + m_state_p: np.ndarray[np.float, dim=1] + Observed state vector. shape: (dim_obs_p,) + + Returns + ------- + m_state_p: np.ndarray[np.float64, dim=1] + Observed state vector. shape: (dim_obs_p,) diff --git a/pyPDAF/source/docs/source/user_desc/py__obs_op_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__obs_op_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..971bbe3b142b59027b906cdd7e47bcf4b3687e3b --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__obs_op_pdaf.rst @@ -0,0 +1,28 @@ +py__obs_op_pdaf +=================== + +.. py:function:: py__obs_op_pdaf(step: int, dim_p: int, dim_obs_p: int, state_p: np.ndarray, m_state_p: np.ndarray) -> np.ndarray + + Apply observation operator + + This function computes :math:`\mathbf{H} \mathbf{x}`, where + :math:`\mathbf{H}` is the observation operator and + :math:`\mathbf{x}` is state vector. + + Parameters + ---------- + step : int + Current step + dim_p : int + Dimension of state vector + dim_obs_p: int + Dimension of observation vector + state_p: np.ndarray[np.float, dim=1] + State vector. shape: (dim_p,) + m_state_p: np.ndarray[np.float, dim=1] + Observed state vector. shape: (dim_obs_p,) + + Returns + ------- + m_state_p: np.ndarray[np.float64, dim=1] + Observed state vector. shape: (dim_obs_p,) diff --git a/pyPDAF/source/docs/source/user_desc/py__prepoststep_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__prepoststep_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..85a7c0f826128a9182d3edb5b84705768054fd0a --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__prepoststep_pdaf.rst @@ -0,0 +1,56 @@ +py__prepoststep_pdaf +==================== + +.. py:function:: py__prepoststep_pdaf(step: int, dim_p: int, dim_ens: int, dim_ens_l: int, dim_obs_p: int, state_p: np.ndarray, uinv: np.ndarray, ens_p: np.ndarray, flag: int) -> Tuple[np.ndarray, np.ndarray, np.ndarray] + + Process ensemble before or after DA. + + Parameters + ---------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) diff --git a/pyPDAF/source/docs/source/user_desc/py__prodrinva_hyb_l_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__prodrinva_hyb_l_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..06f04013026ec367f4d91abba4ddc061a75bfa8d --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__prodrinva_hyb_l_pdaf.rst @@ -0,0 +1,42 @@ +py__prodrinva_hyb_l_pdaf +======================== + +.. py:function:: py__prodrinva_hyb_l_pdaf(domain_p: int, step: int, dim_obs_l: int, rank: int, obs_l: np.ndarray, gamma: float, a_l: np.ndarray, c_l: np.ndarray) -> np.ndarray + + Provide :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l` with weighting. + + Here, one should do :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l`. + The matrix :math:`\mathbf{A}_l` depends on the filter algorithm. + + This function is used in LKNETF where `gamma` is multipled with `c_l` for + weighting between LETKF and LNETF. + + One can also perform observation localisation. This can be helped by the function + :func:`pyPDAF.PDAF.local_weight` to get the observation weight. + + Parameters + ---------- + domain_p: int + Current local domain index. + step: int + Current time step + dim_obs_l: int + Dimension of observation vector in local analysis domain + rank: int + Rank of the local analysis domain + The size of it dpends on the filter algorithms. + obs_l: np.ndarray[np.float, dim=1] + Observation vector in local analysis domain. shape: (dim_obs_l, ) + gamma: float + Hybrid weight provided by PDAF + a_l: np.ndarray[np.float, dim=2] + Matrix A in local analysis domain. shape: (dim_obs_l, rank) + c_l: np.ndarray[np.float, dim=2] + :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l` in local analysis domain. + shape: (dim_obs_l, rank) + + Returns + ------- + c_l: np.ndarray[np.float, dim=2] + :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l` in local analysis domain. + shape: (dim_obs_l, rank) diff --git a/pyPDAF/source/docs/source/user_desc/py__prodrinva_l_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__prodrinva_l_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..34c8ee67ec06a5d6a2477b21408e2eea230754ba --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__prodrinva_l_pdaf.rst @@ -0,0 +1,38 @@ +py__prodrinva_l_pdaf +==================== + +.. py:function:: py__prodrinva_l_pdaf(domain_p: int, step: int, dim_obs_l: int, rank: int, obs_l: np.ndarray, a_l: np.ndarray, c_l: np.ndarray) -> Tuple[np.ndarray, np.ndarray] + + Provide :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l`. + + Here, one should do :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l`. + The matrix :math:`\mathbf{A}_l` depends on the filter algorithm. + + One can also perform observation localisation. This can be helped by the function + :func:`pyPDAF.PDAF.local_weight` to get the observation weight. + + Parameters + ---------- + domain_p: int + Current local domain index. + step: int + Current time step + dim_obs_l: int + Dimension of observation vector in local analysis domain + rank: int + Rank of the local analysis domain + The size of it dpends on the filter algorithms. + obs_l: np.ndarray[np.float, dim=1] + Observation vector in local analysis domain. shape: (dim_obs_l, ) + a_l: np.ndarray[np.float, dim=2] + Matrix A in local analysis domain. + shape: (dim_obs_l, rank) + c_l: np.ndarray[np.float, dim=2] + :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l` in local analysis domain. + shape: (dim_obs_l, rank) + + Returns + ------- + c_l: np.ndarray[np.float, dim=2] + :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l` in local analysis domain. + shape: (dim_obs_l, rank) diff --git a/pyPDAF/source/docs/source/user_desc/py__prodrinva_pdaf.rst b/pyPDAF/source/docs/source/user_desc/py__prodrinva_pdaf.rst new file mode 100644 index 0000000000000000000000000000000000000000..c333285f3862378be0a22cd8f09ac9ef9bb14bf1 --- /dev/null +++ b/pyPDAF/source/docs/source/user_desc/py__prodrinva_pdaf.rst @@ -0,0 +1,34 @@ +py__prodrinva_pdaf +================== + +.. py:function:: py__prodrinva_pdaf(step: int, dim_obs_p: int, rank: int, obs_p: np.ndarray, a_p: np.ndarray, c_p: np.ndarray) -> np.ndarray + + Provide :math:`\mathbf{R}^{-1} \times \mathbf{A}`. + + Here, one should compute :math:`\mathbf{R}^{-1} \times \mathbf{A}` where + :math:`\mathbf{R}` is observation error covariance matrix. + The matrix :math:`\mathbf{A}` depends on the filter algorithm. In ESTKF, + :math:`\mathbf{R}` can is ensemble perturbation in observation space. + + Parameters + ---------- + step : int + Current time step + dim_obs_p : int + Dimension of observation vector + rank: int + Rank of the matrix A (second dimension of A) + This is ensemble size for ETKF and ensemble size - 1 for ESTKF. + obs_p: np.ndarray[np.float, dim=1] + Observation vector. shape: (dim_obs_p,) + a_p: np.ndarray[np.float, dim=2] + Input matrix A. shape: (dim_obs_p, rank) + c_p: np.ndarray[np.float, dim=2] + Output matrix :math:`\mathbf{C} = \mathbf{R}^{-1} \times \mathbf{A}`. + shape: (dim_obs_p, rank) + + Returns + ------- + c_p: np.ndarray[np.float64, dim=2] + Output matrix :math:`\mathbf{C} = \mathbf{R}^{-1} \times \mathbf{A}`. + shape: (dim_obs_p, rank) diff --git a/pyPDAF/source/docs/source/user_functions.rst b/pyPDAF/source/docs/source/user_functions.rst new file mode 100644 index 0000000000000000000000000000000000000000..22cc955bf786f2eb6a60c5612503fe17e1ef6063 --- /dev/null +++ b/pyPDAF/source/docs/source/user_functions.rst @@ -0,0 +1,48 @@ +User-supplied functions +======================= + +Here, we list the documentation of user-supplied functions. + +.. toctree:: + :titlesonly: + :name: user_func + + user_desc/py__add_obs_err_pdaf + user_desc/py__collect_state_pdaf + user_desc/py__cvt_adj_ens_pdaf + user_desc/py__cvt_adj_pdaf + user_desc/py__cvt_ens_pdaf + user_desc/py__cvt_pdaf + user_desc/py__distribute_state_pdaf + user_desc/py__g2l_obs_pdaf + user_desc/py__g2l_state_pdaf + user_desc/py__get_obs_f_pdaf + user_desc/py__init_dim_l_pdaf + user_desc/py__init_dim_obs_f_pdaf + user_desc/py__init_dim_obs_l_pdaf + user_desc/py__init_dim_obs_pdaf + user_desc/py__init_ens_pdaf + user_desc/py__init_n_domains_p_pdaf + user_desc/py__init_obs_covar_pdaf + user_desc/py__init_obs_f_pdaf + user_desc/py__init_obs_l_pdaf + user_desc/py__init_obs_pdaf + user_desc/py__init_obserr_f_pdaf + user_desc/py__init_obsvar_l_pdaf + user_desc/py__init_obsvar_pdaf + user_desc/py__init_obsvars_pdaf + user_desc/py__l2g_state_pdaf + user_desc/py__likelihood_hyb_l_pdaf + user_desc/py__likelihood_l_pdaf + user_desc/py__likelihood_pdaf + user_desc/py__localize_covar_pdaf + user_desc/py__localize_covar_serial_pdaf + user_desc/py__next_observation_pdaf + user_desc/py__obs_op_adj_pdaf + user_desc/py__obs_op_f_pdaf + user_desc/py__obs_op_lin_pdaf + user_desc/py__obs_op_pdaf + user_desc/py__prepoststep_pdaf + user_desc/py__prodrinva_hyb_l_pdaf + user_desc/py__prodrinva_l_pdaf + user_desc/py__prodrinva_pdaf diff --git a/pyPDAF/source/example/inputs_offline/ens_1.txt b/pyPDAF/source/example/inputs_offline/ens_1.txt new file mode 100644 index 0000000000000000000000000000000000000000..9ebcf6ca558c4dfef7c5ecc8e1e81fd3c816d3e5 --- /dev/null +++ b/pyPDAF/source/example/inputs_offline/ens_1.txt @@ -0,0 +1,18 @@ + 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 + 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 + 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 + 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 + 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 + 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 + 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 + 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 + 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 + 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 + 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 + -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 + -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 + -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 + -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 + -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 + -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 + -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 diff --git a/pyPDAF/source/example/inputs_offline/ens_2.txt b/pyPDAF/source/example/inputs_offline/ens_2.txt new file mode 100644 index 0000000000000000000000000000000000000000..972aa0a13aa249164f22f42f8fd808a121ed9d37 --- /dev/null +++ b/pyPDAF/source/example/inputs_offline/ens_2.txt @@ -0,0 +1,18 @@ + 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 + 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 + 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 + 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 + 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 + 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 + 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 + 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 + 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 + 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 + -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 + -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 + -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 + -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 + -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 + -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 + -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 + -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 diff --git a/pyPDAF/source/example/inputs_offline/ens_3.txt b/pyPDAF/source/example/inputs_offline/ens_3.txt new file mode 100644 index 0000000000000000000000000000000000000000..0828c40ae690942b9af3da86c2b817ab3610f3f5 --- /dev/null +++ b/pyPDAF/source/example/inputs_offline/ens_3.txt @@ -0,0 +1,18 @@ + 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 + 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 + 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 + 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 + 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 + 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 + 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 + 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 + 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 + -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 + -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 + -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 + -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 + -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 + -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 + -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 + -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 + -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 diff --git a/pyPDAF/source/example/inputs_offline/ens_4.txt b/pyPDAF/source/example/inputs_offline/ens_4.txt new file mode 100644 index 0000000000000000000000000000000000000000..0399590ba02709f039723fd185c954787d81d726 --- /dev/null +++ b/pyPDAF/source/example/inputs_offline/ens_4.txt @@ -0,0 +1,18 @@ + 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 + 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 + 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 + 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 + 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 + 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 + 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 + 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 + -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 + -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 + -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 + -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 + -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 + -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 + -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 + -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 + -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 + -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 diff --git a/pyPDAF/source/example/inputs_offline/ens_5.txt b/pyPDAF/source/example/inputs_offline/ens_5.txt new file mode 100644 index 0000000000000000000000000000000000000000..8f96af9bd03fd3d5628cbf176489e878012e4f50 --- /dev/null +++ b/pyPDAF/source/example/inputs_offline/ens_5.txt @@ -0,0 +1,18 @@ + 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 + 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 + 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 + 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 + 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 + 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 + 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 + -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 + -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 + -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 + -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 + -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 + -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 + -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 + -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 + -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 + -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 + -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 diff --git a/pyPDAF/source/example/inputs_offline/ens_6.txt b/pyPDAF/source/example/inputs_offline/ens_6.txt new file mode 100644 index 0000000000000000000000000000000000000000..8e5a22c5728d903832b2b0f71574ec4ed9dd0ee8 --- /dev/null +++ b/pyPDAF/source/example/inputs_offline/ens_6.txt @@ -0,0 +1,18 @@ + 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 + 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 + 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 + 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 + 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 + 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 + -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 + -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 + -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 + -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 + -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 + -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 + -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 + -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 + -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 + -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 + -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 + -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 diff --git a/pyPDAF/source/example/inputs_offline/ens_7.txt b/pyPDAF/source/example/inputs_offline/ens_7.txt new file mode 100644 index 0000000000000000000000000000000000000000..201462ee3b83a3f81273f2c5928eca7f1f261e42 --- /dev/null +++ b/pyPDAF/source/example/inputs_offline/ens_7.txt @@ -0,0 +1,18 @@ + 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 + 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 + 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 + 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 + 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 + -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 + -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 + -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 + -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 + -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 + -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 + -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 + -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 + -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 + -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 + -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 + -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 + -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 diff --git a/pyPDAF/source/example/inputs_offline/ens_8.txt b/pyPDAF/source/example/inputs_offline/ens_8.txt new file mode 100644 index 0000000000000000000000000000000000000000..cbd19895fa12a468c340e5063f7c8649ec3dbfb7 --- /dev/null +++ b/pyPDAF/source/example/inputs_offline/ens_8.txt @@ -0,0 +1,18 @@ + 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 + 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 + 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 + 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 + -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 + -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 + -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 + -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 + -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 + -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 + -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 + -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 + -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 + -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 + -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 + -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 + -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 + -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 diff --git a/pyPDAF/source/example/inputs_offline/ens_9.txt b/pyPDAF/source/example/inputs_offline/ens_9.txt new file mode 100644 index 0000000000000000000000000000000000000000..d6415744e847d044ad65d8c904a55eb24728af58 --- /dev/null +++ b/pyPDAF/source/example/inputs_offline/ens_9.txt @@ -0,0 +1,18 @@ + 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 + 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 + 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 + -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 + -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 + -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 + -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 + -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 + -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 + -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 + -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 + -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 + -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 + -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 + -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 + -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 + -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 + -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 0.08715574 0.17364818 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 diff --git a/pyPDAF/source/example/inputs_offline/obs.txt b/pyPDAF/source/example/inputs_offline/obs.txt new file mode 100644 index 0000000000000000000000000000000000000000..c0b7e0efd77df10524b3456427fdb50ab013f19a --- /dev/null +++ b/pyPDAF/source/example/inputs_offline/obs.txt @@ -0,0 +1,18 @@ + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.205173 -999.000000 -999.000000 -999.000000 -999.000000 1.153768 -999.000000 -999.000000 -999.000000 -999.000000 0.788080 -999.000000 -999.000000 -999.000000 -999.000000 1.430938 -999.000000 -999.000000 -999.000000 -999.000000 -0.404703 -999.000000 -999.000000 -999.000000 -999.000000 -0.155908 -999.000000 -999.000000 -999.000000 -999.000000 -0.451339 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.867899 -999.000000 -999.000000 -999.000000 -999.000000 1.161752 -999.000000 -999.000000 -999.000000 -999.000000 0.591400 -999.000000 -999.000000 -999.000000 -999.000000 0.042594 -999.000000 -999.000000 -999.000000 -999.000000 -0.586025 -999.000000 -999.000000 -999.000000 -999.000000 -0.648140 -999.000000 -999.000000 -999.000000 -999.000000 0.053512 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 1.367426 -999.000000 -999.000000 -999.000000 -999.000000 0.340404 -999.000000 -999.000000 -999.000000 -999.000000 -0.397851 -999.000000 -999.000000 -999.000000 -999.000000 -1.545474 -999.000000 -999.000000 -999.000000 -999.000000 -0.707574 -999.000000 -999.000000 -999.000000 -999.000000 -1.611297 -999.000000 -999.000000 -999.000000 -999.000000 -0.693565 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.209013 -999.000000 -999.000000 -999.000000 -999.000000 -0.408155 -999.000000 -999.000000 -999.000000 -999.000000 -1.425576 -999.000000 -999.000000 -999.000000 -999.000000 -0.703224 -999.000000 -999.000000 -999.000000 -999.000000 -0.147926 -999.000000 -999.000000 -999.000000 -999.000000 -0.100437 -999.000000 -999.000000 -999.000000 -999.000000 -0.444410 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 diff --git a/pyPDAF/source/example/inputs_offline/obsB.txt b/pyPDAF/source/example/inputs_offline/obsB.txt new file mode 100644 index 0000000000000000000000000000000000000000..b3361c4b83e3a29b14f3801d0db830f2a9c60c98 --- /dev/null +++ b/pyPDAF/source/example/inputs_offline/obsB.txt @@ -0,0 +1,18 @@ + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 0.460117 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 0.434031 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -1.349768 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 0.499765 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -0.353181 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -0.590311 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 diff --git a/pyPDAF/source/example/inputs_offline/obsC.txt b/pyPDAF/source/example/inputs_offline/obsC.txt new file mode 100644 index 0000000000000000000000000000000000000000..af85ef7cf5beed8f96a738a96762bb009a2a2186 --- /dev/null +++ b/pyPDAF/source/example/inputs_offline/obsC.txt @@ -0,0 +1,12 @@ + 11 + 0.633484 3.000000 2.100000 + 0.803791 3.400000 6.800000 + 0.244921 6.100000 6.800000 + 0.836253 8.900000 7.600000 + 0.247297 8.900000 14.900000 + 1.143794 20.000000 6.400000 + -1.205377 20.400000 16.100000 + -0.683405 14.100000 10.200000 + -0.369636 31.000000 5.200000 + -0.806088 31.200000 11.900000 + -1.028938 28.900000 14.900000 diff --git a/pyPDAF/source/example/inputs_offline/state_ini.txt b/pyPDAF/source/example/inputs_offline/state_ini.txt new file mode 100644 index 0000000000000000000000000000000000000000..e2c0a889fc3da6a5d389fcdc94bf4a21fabd0ab3 --- /dev/null +++ b/pyPDAF/source/example/inputs_offline/state_ini.txt @@ -0,0 +1,18 @@ + 0.817000 0.780687 0.738433 0.690558 0.637429 0.579447 0.517056 0.450730 0.380973 0.308317 0.233315 0.156537 0.078567 0.000000 -0.078567 -0.156537 -0.233315 -0.308317 -0.380973 -0.450730 -0.517056 -0.579447 -0.637429 -0.690558 -0.738433 -0.780687 -0.817000 -0.847095 -0.870744 -0.887765 -0.898030 -0.901460 -0.898030 -0.887765 -0.870744 -0.847095 + 0.738433 0.690558 0.637429 0.579447 0.517056 0.450730 0.380973 0.308317 0.233315 0.156537 0.078567 0.000000 -0.078567 -0.156537 -0.233315 -0.308317 -0.380973 -0.450730 -0.517056 -0.579447 -0.637429 -0.690558 -0.738433 -0.780687 -0.817000 -0.847095 -0.870744 -0.887765 -0.898030 -0.901460 -0.898030 -0.887765 -0.870744 -0.847095 -0.817000 -0.780687 + 0.637429 0.579447 0.517056 0.450730 0.380973 0.308317 0.233315 0.156537 0.078567 0.000000 -0.078567 -0.156537 -0.233315 -0.308317 -0.380973 -0.450730 -0.517056 -0.579447 -0.637429 -0.690558 -0.738433 -0.780687 -0.817000 -0.847095 -0.870744 -0.887765 -0.898030 -0.901460 -0.898030 -0.887765 -0.870744 -0.847095 -0.817000 -0.780687 -0.738433 -0.690558 + 0.517056 0.450730 0.380973 0.308317 0.233315 0.156537 0.078567 0.000000 -0.078567 -0.156537 -0.233315 -0.308317 -0.380973 -0.450730 -0.517056 -0.579447 -0.637429 -0.690558 -0.738433 -0.780687 -0.817000 -0.847095 -0.870744 -0.887765 -0.898030 -0.901460 -0.898030 -0.887765 -0.870744 -0.847095 -0.817000 -0.780687 -0.738433 -0.690558 -0.637429 -0.579447 + 0.380973 0.308317 0.233315 0.156537 0.078567 0.000000 -0.078567 -0.156537 -0.233315 -0.308317 -0.380973 -0.450730 -0.517056 -0.579447 -0.637429 -0.690558 -0.738433 -0.780687 -0.817000 -0.847095 -0.870744 -0.887765 -0.898030 -0.901460 -0.898030 -0.887765 -0.870744 -0.847095 -0.817000 -0.780687 -0.738433 -0.690558 -0.637429 -0.579447 -0.517056 -0.450730 + 0.233315 0.156537 0.078567 0.000000 -0.078567 -0.156537 -0.233315 -0.308317 -0.380973 -0.450730 -0.517056 -0.579447 -0.637429 -0.690558 -0.738433 -0.780687 -0.817000 -0.847095 -0.870744 -0.887765 -0.898030 -0.901460 -0.898030 -0.887765 -0.870744 -0.847095 -0.817000 -0.780687 -0.738433 -0.690558 -0.637429 -0.579447 -0.517056 -0.450730 -0.380973 -0.308317 + 0.078567 0.000000 -0.078567 -0.156537 -0.233315 -0.308317 -0.380973 -0.450730 -0.517056 -0.579447 -0.637429 -0.690558 -0.738433 -0.780687 -0.817000 -0.847095 -0.870744 -0.887765 -0.898030 -0.901460 -0.898030 -0.887765 -0.870744 -0.847095 -0.817000 -0.780687 -0.738433 -0.690558 -0.637429 -0.579447 -0.517056 -0.450730 -0.380973 -0.308317 -0.233315 -0.156537 + -0.078567 -0.156537 -0.233315 -0.308317 -0.380973 -0.450730 -0.517056 -0.579447 -0.637429 -0.690558 -0.738433 -0.780687 -0.817000 -0.847095 -0.870744 -0.887765 -0.898030 -0.901460 -0.898030 -0.887765 -0.870744 -0.847095 -0.817000 -0.780687 -0.738433 -0.690558 -0.637429 -0.579447 -0.517056 -0.450730 -0.380973 -0.308317 -0.233315 -0.156537 -0.078567 -0.000000 + -0.233315 -0.308317 -0.380973 -0.450730 -0.517056 -0.579447 -0.637429 -0.690558 -0.738433 -0.780687 -0.817000 -0.847095 -0.870744 -0.887765 -0.898030 -0.901460 -0.898030 -0.887765 -0.870744 -0.847095 -0.817000 -0.780687 -0.738433 -0.690558 -0.637429 -0.579447 -0.517056 -0.450730 -0.380973 -0.308317 -0.233315 -0.156537 -0.078567 -0.000000 0.078567 0.156537 + -0.380973 -0.450730 -0.517056 -0.579447 -0.637429 -0.690558 -0.738433 -0.780687 -0.817000 -0.847095 -0.870744 -0.887765 -0.898030 -0.901460 -0.898030 -0.887765 -0.870744 -0.847095 -0.817000 -0.780687 -0.738433 -0.690558 -0.637429 -0.579447 -0.517056 -0.450730 -0.380973 -0.308317 -0.233315 -0.156537 -0.078567 -0.000000 0.078567 0.156537 0.233315 0.308317 + -0.517056 -0.579447 -0.637429 -0.690558 -0.738433 -0.780687 -0.817000 -0.847095 -0.870744 -0.887765 -0.898030 -0.901460 -0.898030 -0.887765 -0.870744 -0.847095 -0.817000 -0.780687 -0.738433 -0.690558 -0.637429 -0.579447 -0.517056 -0.450730 -0.380973 -0.308317 -0.233315 -0.156537 -0.078567 -0.000000 0.078567 0.156537 0.233315 0.308317 0.380973 0.450730 + -0.637429 -0.690558 -0.738433 -0.780687 -0.817000 -0.847095 -0.870744 -0.887765 -0.898030 -0.901460 -0.898030 -0.887765 -0.870744 -0.847095 -0.817000 -0.780687 -0.738433 -0.690558 -0.637429 -0.579447 -0.517056 -0.450730 -0.380973 -0.308317 -0.233315 -0.156537 -0.078567 -0.000000 0.078567 0.156537 0.233315 0.308317 0.380973 0.450730 0.517056 0.579447 + -0.738433 -0.780687 -0.817000 -0.847095 -0.870744 -0.887765 -0.898030 -0.901460 -0.898030 -0.887765 -0.870744 -0.847095 -0.817000 -0.780687 -0.738433 -0.690558 -0.637429 -0.579447 -0.517056 -0.450730 -0.380973 -0.308317 -0.233315 -0.156537 -0.078567 -0.000000 0.078567 0.156537 0.233315 0.308317 0.380973 0.450730 0.517056 0.579447 0.637429 0.690558 + -0.817000 -0.847095 -0.870744 -0.887765 -0.898030 -0.901460 -0.898030 -0.887765 -0.870744 -0.847095 -0.817000 -0.780687 -0.738433 -0.690558 -0.637429 -0.579447 -0.517056 -0.450730 -0.380973 -0.308317 -0.233315 -0.156537 -0.078567 -0.000000 0.078567 0.156537 0.233315 0.308317 0.380973 0.450730 0.517056 0.579447 0.637429 0.690558 0.738433 0.780687 + -0.870744 -0.887765 -0.898030 -0.901460 -0.898030 -0.887765 -0.870744 -0.847095 -0.817000 -0.780687 -0.738433 -0.690558 -0.637429 -0.579447 -0.517056 -0.450730 -0.380973 -0.308317 -0.233315 -0.156537 -0.078567 -0.000000 0.078567 0.156537 0.233315 0.308317 0.380973 0.450730 0.517056 0.579447 0.637429 0.690558 0.738433 0.780687 0.817000 0.847095 + -0.898030 -0.901460 -0.898030 -0.887765 -0.870744 -0.847095 -0.817000 -0.780687 -0.738433 -0.690558 -0.637429 -0.579447 -0.517056 -0.450730 -0.380973 -0.308317 -0.233315 -0.156537 -0.078567 -0.000000 0.078567 0.156537 0.233315 0.308317 0.380973 0.450730 0.517056 0.579447 0.637429 0.690558 0.738433 0.780687 0.817000 0.847095 0.870744 0.887765 + -0.898030 -0.887765 -0.870744 -0.847095 -0.817000 -0.780687 -0.738433 -0.690558 -0.637429 -0.579447 -0.517056 -0.450730 -0.380973 -0.308317 -0.233315 -0.156537 -0.078567 -0.000000 0.078567 0.156537 0.233315 0.308317 0.380973 0.450730 0.517056 0.579447 0.637429 0.690558 0.738433 0.780687 0.817000 0.847095 0.870744 0.887765 0.898030 0.901460 + -0.870744 -0.847095 -0.817000 -0.780687 -0.738433 -0.690558 -0.637429 -0.579447 -0.517056 -0.450730 -0.380973 -0.308317 -0.233315 -0.156537 -0.078567 -0.000000 0.078567 0.156537 0.233315 0.308317 0.380973 0.450730 0.517056 0.579447 0.637429 0.690558 0.738433 0.780687 0.817000 0.847095 0.870744 0.887765 0.898030 0.901460 0.898030 0.887765 diff --git a/pyPDAF/source/example/inputs_offline/true.txt b/pyPDAF/source/example/inputs_offline/true.txt new file mode 100644 index 0000000000000000000000000000000000000000..f95956faacf2752f1bb503b75e81403af9c75c1b --- /dev/null +++ b/pyPDAF/source/example/inputs_offline/true.txt @@ -0,0 +1,18 @@ + 0.25881905 0.34202014 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 + 0.42261826 0.50000000 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 + 0.57357644 0.64278761 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 + 0.70710678 0.76604444 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 + 0.81915204 0.86602540 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 + 0.90630779 0.93969262 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 + 0.96592583 0.98480775 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 + 0.99619470 1.00000000 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 + 0.99619470 0.98480775 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 + 0.96592583 0.93969262 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 + 0.90630779 0.86602540 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 + 0.81915204 0.76604444 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 + 0.70710678 0.64278761 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 + 0.57357644 0.50000000 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 + 0.42261826 0.34202014 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 + 0.25881905 0.17364818 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 + 0.08715574 0.00000000 -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 + -0.08715574 -0.17364818 -0.25881905 -0.34202014 -0.42261826 -0.50000000 -0.57357644 -0.64278761 -0.70710678 -0.76604444 -0.81915204 -0.86602540 -0.90630779 -0.93969262 -0.96592583 -0.98480775 -0.99619470 -1.00000000 -0.99619470 -0.98480775 -0.96592583 -0.93969262 -0.90630779 -0.86602540 -0.81915204 -0.76604444 -0.70710678 -0.64278761 -0.57357644 -0.50000000 -0.42261826 -0.34202014 -0.25881905 -0.17364818 -0.08715574 -0.00000000 diff --git a/pyPDAF/source/example/inputs_online/ensB_1.txt b/pyPDAF/source/example/inputs_online/ensB_1.txt new file mode 100644 index 0000000000000000000000000000000000000000..9d9a06ba1f014cbfedd68f1ca63618bbc8855961 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/ensB_1.txt @@ -0,0 +1,18 @@ + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 + -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 + 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 diff --git a/pyPDAF/source/example/inputs_online/ensB_2.txt b/pyPDAF/source/example/inputs_online/ensB_2.txt new file mode 100644 index 0000000000000000000000000000000000000000..88f46947a62544ab8783b29ed90045e1fc473f69 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/ensB_2.txt @@ -0,0 +1,18 @@ + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 diff --git a/pyPDAF/source/example/inputs_online/ensB_3.txt b/pyPDAF/source/example/inputs_online/ensB_3.txt new file mode 100644 index 0000000000000000000000000000000000000000..bd5fcbe7a310ba766f42ec4a4a644a8ba3d852e2 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/ensB_3.txt @@ -0,0 +1,18 @@ + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 diff --git a/pyPDAF/source/example/inputs_online/ensB_4.txt b/pyPDAF/source/example/inputs_online/ensB_4.txt new file mode 100644 index 0000000000000000000000000000000000000000..7c60f3ae6a50b7457f3db15883febdabcbd8c817 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/ensB_4.txt @@ -0,0 +1,18 @@ + -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 diff --git a/pyPDAF/source/example/inputs_online/ensB_5.txt b/pyPDAF/source/example/inputs_online/ensB_5.txt new file mode 100644 index 0000000000000000000000000000000000000000..f54cd3d8f2942a90517ed2bc77494c01ad669727 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/ensB_5.txt @@ -0,0 +1,18 @@ + -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 + -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 diff --git a/pyPDAF/source/example/inputs_online/ensB_6.txt b/pyPDAF/source/example/inputs_online/ensB_6.txt new file mode 100644 index 0000000000000000000000000000000000000000..491b1c8f65c1ad1a2806d8a699c2ee9da7b12c6a --- /dev/null +++ b/pyPDAF/source/example/inputs_online/ensB_6.txt @@ -0,0 +1,18 @@ + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 + 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 + -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 diff --git a/pyPDAF/source/example/inputs_online/ensB_7.txt b/pyPDAF/source/example/inputs_online/ensB_7.txt new file mode 100644 index 0000000000000000000000000000000000000000..64d5ab0448f5b3d606b678900cf5f796ad6a1cec --- /dev/null +++ b/pyPDAF/source/example/inputs_online/ensB_7.txt @@ -0,0 +1,18 @@ + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 + 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 + -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 diff --git a/pyPDAF/source/example/inputs_online/ensB_8.txt b/pyPDAF/source/example/inputs_online/ensB_8.txt new file mode 100644 index 0000000000000000000000000000000000000000..c893bb192179cca3c571a2bb8b142c2fccd1d050 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/ensB_8.txt @@ -0,0 +1,18 @@ + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 + -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 diff --git a/pyPDAF/source/example/inputs_online/ensB_9.txt b/pyPDAF/source/example/inputs_online/ensB_9.txt new file mode 100644 index 0000000000000000000000000000000000000000..328c431f1c36c0cb61d0f71515a38fa73d63c209 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/ensB_9.txt @@ -0,0 +1,18 @@ + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 + -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 -0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 diff --git a/pyPDAF/source/example/inputs_online/ens_1.txt b/pyPDAF/source/example/inputs_online/ens_1.txt new file mode 100644 index 0000000000000000000000000000000000000000..549c410499142bc5e69facb38b0804ee37867244 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/ens_1.txt @@ -0,0 +1,18 @@ + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 diff --git a/pyPDAF/source/example/inputs_online/ens_2.txt b/pyPDAF/source/example/inputs_online/ens_2.txt new file mode 100644 index 0000000000000000000000000000000000000000..db911471da892c730d79e2ad5c03fab459dd4aff --- /dev/null +++ b/pyPDAF/source/example/inputs_online/ens_2.txt @@ -0,0 +1,18 @@ + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 diff --git a/pyPDAF/source/example/inputs_online/ens_3.txt b/pyPDAF/source/example/inputs_online/ens_3.txt new file mode 100644 index 0000000000000000000000000000000000000000..5be8b182ff3b1380ea3f315658f11b4cda85d23a --- /dev/null +++ b/pyPDAF/source/example/inputs_online/ens_3.txt @@ -0,0 +1,18 @@ + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 diff --git a/pyPDAF/source/example/inputs_online/ens_4.txt b/pyPDAF/source/example/inputs_online/ens_4.txt new file mode 100644 index 0000000000000000000000000000000000000000..3bdd4570360f5b1b5890ae62c4970b25100ae6bd --- /dev/null +++ b/pyPDAF/source/example/inputs_online/ens_4.txt @@ -0,0 +1,18 @@ + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 diff --git a/pyPDAF/source/example/inputs_online/ens_5.txt b/pyPDAF/source/example/inputs_online/ens_5.txt new file mode 100644 index 0000000000000000000000000000000000000000..7170ccf8d81553d076001b39e693e04ccd597cb4 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/ens_5.txt @@ -0,0 +1,18 @@ + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 diff --git a/pyPDAF/source/example/inputs_online/ens_6.txt b/pyPDAF/source/example/inputs_online/ens_6.txt new file mode 100644 index 0000000000000000000000000000000000000000..86ed2982ec6cb30b4fd8f8e2b62ad29ba331197b --- /dev/null +++ b/pyPDAF/source/example/inputs_online/ens_6.txt @@ -0,0 +1,18 @@ + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 diff --git a/pyPDAF/source/example/inputs_online/ens_7.txt b/pyPDAF/source/example/inputs_online/ens_7.txt new file mode 100644 index 0000000000000000000000000000000000000000..ea4a2cf25d4630b57b82bf3bf506bea64def7ff6 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/ens_7.txt @@ -0,0 +1,18 @@ + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 diff --git a/pyPDAF/source/example/inputs_online/ens_8.txt b/pyPDAF/source/example/inputs_online/ens_8.txt new file mode 100644 index 0000000000000000000000000000000000000000..b50375d66ec0ed4426196d4866505e7f85b106a0 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/ens_8.txt @@ -0,0 +1,18 @@ + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 diff --git a/pyPDAF/source/example/inputs_online/ens_9.txt b/pyPDAF/source/example/inputs_online/ens_9.txt new file mode 100644 index 0000000000000000000000000000000000000000..88389e7b3e1de56927cb099995ef6e459c1c7ce5 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/ens_9.txt @@ -0,0 +1,18 @@ + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 diff --git a/pyPDAF/source/example/inputs_online/iobs_step1.txt b/pyPDAF/source/example/inputs_online/iobs_step1.txt new file mode 100644 index 0000000000000000000000000000000000000000..dff7a8c630c946a9c108d2351cb503dd414dfb0a --- /dev/null +++ b/pyPDAF/source/example/inputs_online/iobs_step1.txt @@ -0,0 +1,12 @@ + 11 + 1.440704 3.000000 2.100000 + 1.030067 3.400000 6.800000 + -0.279396 6.100000 6.800000 + -1.864832 8.900000 7.600000 + 0.162171 8.900000 14.900000 + -0.878268 20.000000 6.400000 + 1.751827 20.400000 16.100000 + -0.249494 14.100000 10.200000 + 0.219307 31.000000 5.200000 + -0.580049 31.200000 11.900000 + -1.059334 28.900000 14.900000 diff --git a/pyPDAF/source/example/inputs_online/iobs_step10.txt b/pyPDAF/source/example/inputs_online/iobs_step10.txt new file mode 100644 index 0000000000000000000000000000000000000000..1da7833a982cee5a2ad123812153896a3558d4ba --- /dev/null +++ b/pyPDAF/source/example/inputs_online/iobs_step10.txt @@ -0,0 +1,12 @@ + 11 + -1.087938 3.000000 2.100000 + -0.314608 3.400000 6.800000 + 0.888354 6.100000 6.800000 + 0.650526 8.900000 7.600000 + -0.774846 8.900000 14.900000 + 0.510848 20.000000 6.400000 + -0.344142 20.400000 16.100000 + 0.285234 14.100000 10.200000 + -0.110990 31.000000 5.200000 + 0.986413 31.200000 11.900000 + 1.144590 28.900000 14.900000 diff --git a/pyPDAF/source/example/inputs_online/iobs_step11.txt b/pyPDAF/source/example/inputs_online/iobs_step11.txt new file mode 100644 index 0000000000000000000000000000000000000000..0eacd2a3c4c84b874d3c1d94f5b5d9118a46f3eb --- /dev/null +++ b/pyPDAF/source/example/inputs_online/iobs_step11.txt @@ -0,0 +1,12 @@ + 11 + -0.483313 3.000000 2.100000 + -0.983515 3.400000 6.800000 + 0.701286 6.100000 6.800000 + 0.571197 8.900000 7.600000 + 0.732088 8.900000 14.900000 + 0.851163 20.000000 6.400000 + -1.867291 20.400000 16.100000 + 0.354012 14.100000 10.200000 + -0.434015 31.000000 5.200000 + -0.375117 31.200000 11.900000 + 0.415634 28.900000 14.900000 diff --git a/pyPDAF/source/example/inputs_online/iobs_step12.txt b/pyPDAF/source/example/inputs_online/iobs_step12.txt new file mode 100644 index 0000000000000000000000000000000000000000..d5d40b4a91c86d65bbea4f0ea97a23f07ec5ada1 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/iobs_step12.txt @@ -0,0 +1,12 @@ + 11 + 0.106948 3.000000 2.100000 + -1.474745 3.400000 6.800000 + -1.181350 6.100000 6.800000 + 0.103815 8.900000 7.600000 + -0.046754 8.900000 14.900000 + 1.262671 20.000000 6.400000 + -1.158448 20.400000 16.100000 + 1.561389 14.100000 10.200000 + -0.185308 31.000000 5.200000 + -1.356173 31.200000 11.900000 + 0.229932 28.900000 14.900000 diff --git a/pyPDAF/source/example/inputs_online/iobs_step13.txt b/pyPDAF/source/example/inputs_online/iobs_step13.txt new file mode 100644 index 0000000000000000000000000000000000000000..13e94b96c3b733fbd16b6fdfa608771786a78869 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/iobs_step13.txt @@ -0,0 +1,12 @@ + 11 + 0.454786 3.000000 2.100000 + -0.270052 3.400000 6.800000 + -2.006515 6.100000 6.800000 + 0.121701 8.900000 7.600000 + 0.784293 8.900000 14.900000 + 1.510069 20.000000 6.400000 + -0.197725 20.400000 16.100000 + 1.079600 14.100000 10.200000 + 0.256029 31.000000 5.200000 + -0.147373 31.200000 11.900000 + -0.685513 28.900000 14.900000 diff --git a/pyPDAF/source/example/inputs_online/iobs_step14.txt b/pyPDAF/source/example/inputs_online/iobs_step14.txt new file mode 100644 index 0000000000000000000000000000000000000000..75d8404beb4642895f3392817e5369567494acf5 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/iobs_step14.txt @@ -0,0 +1,12 @@ + 11 + 0.308004 3.000000 2.100000 + -0.932708 3.400000 6.800000 + -1.801808 6.100000 6.800000 + -0.686440 8.900000 7.600000 + 0.940538 8.900000 14.900000 + 0.064342 20.000000 6.400000 + -1.555299 20.400000 16.100000 + 0.817198 14.100000 10.200000 + 0.559251 31.000000 5.200000 + -0.452348 31.200000 11.900000 + -1.184486 28.900000 14.900000 diff --git a/pyPDAF/source/example/inputs_online/iobs_step15.txt b/pyPDAF/source/example/inputs_online/iobs_step15.txt new file mode 100644 index 0000000000000000000000000000000000000000..3d4ac170b23d4b60168eab763d23dac4867a2c4f --- /dev/null +++ b/pyPDAF/source/example/inputs_online/iobs_step15.txt @@ -0,0 +1,12 @@ + 11 + -0.042587 3.000000 2.100000 + -1.067172 3.400000 6.800000 + -1.085929 6.100000 6.800000 + -1.954364 8.900000 7.600000 + 0.502974 8.900000 14.900000 + 0.535730 20.000000 6.400000 + -0.754804 20.400000 16.100000 + 0.675158 14.100000 10.200000 + 0.546534 31.000000 5.200000 + -0.350847 31.200000 11.900000 + -0.501185 28.900000 14.900000 diff --git a/pyPDAF/source/example/inputs_online/iobs_step16.txt b/pyPDAF/source/example/inputs_online/iobs_step16.txt new file mode 100644 index 0000000000000000000000000000000000000000..dd2f7dc0c776716086faffa0a164d84d9df7cf4e --- /dev/null +++ b/pyPDAF/source/example/inputs_online/iobs_step16.txt @@ -0,0 +1,12 @@ + 11 + 1.297696 3.000000 2.100000 + -0.000010 3.400000 6.800000 + -0.488604 6.100000 6.800000 + -1.914671 8.900000 7.600000 + 1.523898 8.900000 14.900000 + 0.288788 20.000000 6.400000 + -1.781227 20.400000 16.100000 + 0.554839 14.100000 10.200000 + 0.451150 31.000000 5.200000 + -0.851394 31.200000 11.900000 + -0.482287 28.900000 14.900000 diff --git a/pyPDAF/source/example/inputs_online/iobs_step17.txt b/pyPDAF/source/example/inputs_online/iobs_step17.txt new file mode 100644 index 0000000000000000000000000000000000000000..fb801f667591f70c3c4bc6907bc8dbe1a44a267d --- /dev/null +++ b/pyPDAF/source/example/inputs_online/iobs_step17.txt @@ -0,0 +1,12 @@ + 11 + 0.916565 3.000000 2.100000 + -0.664629 3.400000 6.800000 + -0.840185 6.100000 6.800000 + -0.514533 8.900000 7.600000 + 0.130826 8.900000 14.900000 + -0.031573 20.000000 6.400000 + -0.078692 20.400000 16.100000 + 0.568579 14.100000 10.200000 + 1.417049 31.000000 5.200000 + -0.670591 31.200000 11.900000 + -1.311510 28.900000 14.900000 diff --git a/pyPDAF/source/example/inputs_online/iobs_step18.txt b/pyPDAF/source/example/inputs_online/iobs_step18.txt new file mode 100644 index 0000000000000000000000000000000000000000..bc3c68a3907448ab4711be8e17ad2e1993bc1d9b --- /dev/null +++ b/pyPDAF/source/example/inputs_online/iobs_step18.txt @@ -0,0 +1,12 @@ + 11 + 1.012191 3.000000 2.100000 + -0.161802 3.400000 6.800000 + -0.313103 6.100000 6.800000 + -1.613005 8.900000 7.600000 + 0.114747 8.900000 14.900000 + -0.922685 20.000000 6.400000 + 0.126156 20.400000 16.100000 + -0.026603 14.100000 10.200000 + 1.083992 31.000000 5.200000 + 0.350631 31.200000 11.900000 + -0.222497 28.900000 14.900000 diff --git a/pyPDAF/source/example/inputs_online/iobs_step2.txt b/pyPDAF/source/example/inputs_online/iobs_step2.txt new file mode 100644 index 0000000000000000000000000000000000000000..f3788708ce8364aa090b1fa290cdc9a6a61b5b41 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/iobs_step2.txt @@ -0,0 +1,12 @@ + 11 + 0.079950 3.000000 2.100000 + 0.207952 3.400000 6.800000 + 0.164999 6.100000 6.800000 + -1.204712 8.900000 7.600000 + -1.137463 8.900000 14.900000 + -1.880246 20.000000 6.400000 + 0.962238 20.400000 16.100000 + -0.724099 14.100000 10.200000 + 0.268482 31.000000 5.200000 + 2.110168 31.200000 11.900000 + 0.103704 28.900000 14.900000 diff --git a/pyPDAF/source/example/inputs_online/iobs_step3.txt b/pyPDAF/source/example/inputs_online/iobs_step3.txt new file mode 100644 index 0000000000000000000000000000000000000000..3e6ce63a63240fe0213d81b58f1d467add76e094 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/iobs_step3.txt @@ -0,0 +1,12 @@ + 11 + 0.524193 3.000000 2.100000 + 0.831798 3.400000 6.800000 + -0.137427 6.100000 6.800000 + 0.637087 8.900000 7.600000 + 0.042052 8.900000 14.900000 + -0.758810 20.000000 6.400000 + -0.065933 20.400000 16.100000 + -0.612046 14.100000 10.200000 + 0.064063 31.000000 5.200000 + 1.826238 31.200000 11.900000 + 0.254564 28.900000 14.900000 diff --git a/pyPDAF/source/example/inputs_online/iobs_step4.txt b/pyPDAF/source/example/inputs_online/iobs_step4.txt new file mode 100644 index 0000000000000000000000000000000000000000..c20de01d7f26701229ee59d4b9cad0621e5f3453 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/iobs_step4.txt @@ -0,0 +1,12 @@ + 11 + -0.484763 3.000000 2.100000 + 0.517527 3.400000 6.800000 + 0.728930 6.100000 6.800000 + 0.101079 8.900000 7.600000 + -0.253995 8.900000 14.900000 + 0.217874 20.000000 6.400000 + 0.375313 20.400000 16.100000 + -1.080157 14.100000 10.200000 + -0.541174 31.000000 5.200000 + 0.038653 31.200000 11.900000 + 0.628164 28.900000 14.900000 diff --git a/pyPDAF/source/example/inputs_online/iobs_step5.txt b/pyPDAF/source/example/inputs_online/iobs_step5.txt new file mode 100644 index 0000000000000000000000000000000000000000..c93e8e2893acbc36ded3f72ae6469109fc5d7354 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/iobs_step5.txt @@ -0,0 +1,12 @@ + 11 + -0.719613 3.000000 2.100000 + 0.621781 3.400000 6.800000 + 1.572431 6.100000 6.800000 + 0.948718 8.900000 7.600000 + -1.313241 8.900000 14.900000 + -0.298292 20.000000 6.400000 + 0.720236 20.400000 16.100000 + -1.205583 14.100000 10.200000 + -0.720680 31.000000 5.200000 + 0.484556 31.200000 11.900000 + 0.590282 28.900000 14.900000 diff --git a/pyPDAF/source/example/inputs_online/iobs_step6.txt b/pyPDAF/source/example/inputs_online/iobs_step6.txt new file mode 100644 index 0000000000000000000000000000000000000000..3f1ae9c1507fe676cf994318853778a44887ebd9 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/iobs_step6.txt @@ -0,0 +1,12 @@ + 11 + -0.997825 3.000000 2.100000 + 0.614787 3.400000 6.800000 + 0.903311 6.100000 6.800000 + 1.830158 8.900000 7.600000 + -0.606079 8.900000 14.900000 + -0.707820 20.000000 6.400000 + 1.182957 20.400000 16.100000 + -0.287009 14.100000 10.200000 + -0.428112 31.000000 5.200000 + 0.957231 31.200000 11.900000 + 0.278086 28.900000 14.900000 diff --git a/pyPDAF/source/example/inputs_online/iobs_step7.txt b/pyPDAF/source/example/inputs_online/iobs_step7.txt new file mode 100644 index 0000000000000000000000000000000000000000..30db734f11f2a7fd84f272983766e856bd3c2f52 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/iobs_step7.txt @@ -0,0 +1,12 @@ + 11 + -0.612048 3.000000 2.100000 + 0.676139 3.400000 6.800000 + 0.331158 6.100000 6.800000 + 1.902036 8.900000 7.600000 + -1.087707 8.900000 14.900000 + 0.280577 20.000000 6.400000 + -0.074172 20.400000 16.100000 + 0.286335 14.100000 10.200000 + -1.122821 31.000000 5.200000 + 0.494860 31.200000 11.900000 + 1.417252 28.900000 14.900000 diff --git a/pyPDAF/source/example/inputs_online/iobs_step8.txt b/pyPDAF/source/example/inputs_online/iobs_step8.txt new file mode 100644 index 0000000000000000000000000000000000000000..9e7203893548f3b4674b2cc5a31b33c644abc2e4 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/iobs_step8.txt @@ -0,0 +1,12 @@ + 11 + -1.111078 3.000000 2.100000 + 1.023401 3.400000 6.800000 + 1.513302 6.100000 6.800000 + 1.032681 8.900000 7.600000 + 0.513315 8.900000 14.900000 + -0.093643 20.000000 6.400000 + -0.315544 20.400000 16.100000 + -0.723547 14.100000 10.200000 + -1.572238 31.000000 5.200000 + 0.707262 31.200000 11.900000 + 0.708323 28.900000 14.900000 diff --git a/pyPDAF/source/example/inputs_online/iobs_step9.txt b/pyPDAF/source/example/inputs_online/iobs_step9.txt new file mode 100644 index 0000000000000000000000000000000000000000..cedfd3c88e50316f35a9d2017b6a8abad5786e45 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/iobs_step9.txt @@ -0,0 +1,12 @@ + 11 + -0.565340 3.000000 2.100000 + -0.017849 3.400000 6.800000 + -0.026557 6.100000 6.800000 + 0.638334 8.900000 7.600000 + -0.879640 8.900000 14.900000 + 0.627418 20.000000 6.400000 + -0.359695 20.400000 16.100000 + 0.670317 14.100000 10.200000 + -2.315007 31.000000 5.200000 + 1.087363 31.200000 11.900000 + 0.164720 28.900000 14.900000 diff --git a/pyPDAF/source/example/inputs_online/obs_step1.txt b/pyPDAF/source/example/inputs_online/obs_step1.txt new file mode 100644 index 0000000000000000000000000000000000000000..4b37dbfc68ca1c9f2300338f7d1853254e066163 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/obs_step1.txt @@ -0,0 +1,18 @@ + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.575069 -999.000000 -999.000000 -999.000000 -999.000000 0.477209 -999.000000 -999.000000 -999.000000 -999.000000 0.098125 -999.000000 -999.000000 -999.000000 -999.000000 -1.143622 -999.000000 -999.000000 -999.000000 -999.000000 -2.015811 -999.000000 -999.000000 -999.000000 -999.000000 0.005677 -999.000000 -999.000000 -999.000000 -999.000000 0.617962 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.775282 -999.000000 -999.000000 -999.000000 -999.000000 -1.335176 -999.000000 -999.000000 -999.000000 -999.000000 -1.024630 -999.000000 -999.000000 -999.000000 -999.000000 -0.483402 -999.000000 -999.000000 -999.000000 -999.000000 -0.152426 -999.000000 -999.000000 -999.000000 -999.000000 0.961368 -999.000000 -999.000000 -999.000000 -999.000000 0.917827 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -1.604326 -999.000000 -999.000000 -999.000000 -999.000000 -0.998449 -999.000000 -999.000000 -999.000000 -999.000000 0.806912 -999.000000 -999.000000 -999.000000 -999.000000 0.531469 -999.000000 -999.000000 -999.000000 -999.000000 1.216238 -999.000000 -999.000000 -999.000000 -999.000000 -0.196209 -999.000000 -999.000000 -999.000000 -999.000000 -0.636923 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.886866 -999.000000 -999.000000 -999.000000 -999.000000 0.371014 -999.000000 -999.000000 -999.000000 -999.000000 0.612743 -999.000000 -999.000000 -999.000000 -999.000000 0.253741 -999.000000 -999.000000 -999.000000 -999.000000 0.423005 -999.000000 -999.000000 -999.000000 -999.000000 -1.005456 -999.000000 -999.000000 -999.000000 -999.000000 -0.953473 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 diff --git a/pyPDAF/source/example/inputs_online/obs_step10.txt b/pyPDAF/source/example/inputs_online/obs_step10.txt new file mode 100644 index 0000000000000000000000000000000000000000..abc29081d53a5987f14a3a14364f91df81d166c7 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/obs_step10.txt @@ -0,0 +1,18 @@ + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.230514 -999.000000 -999.000000 -999.000000 -999.000000 -0.965459 -999.000000 -999.000000 -999.000000 -999.000000 0.293624 -999.000000 -999.000000 -999.000000 -999.000000 1.808876 -999.000000 -999.000000 -999.000000 -999.000000 1.165317 -999.000000 -999.000000 -999.000000 -999.000000 0.578555 -999.000000 -999.000000 -999.000000 -999.000000 -0.817730 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.166373 -999.000000 -999.000000 -999.000000 -999.000000 1.120509 -999.000000 -999.000000 -999.000000 -999.000000 0.832616 -999.000000 -999.000000 -999.000000 -999.000000 0.034035 -999.000000 -999.000000 -999.000000 -999.000000 -0.373281 -999.000000 -999.000000 -999.000000 -999.000000 -1.045216 -999.000000 -999.000000 -999.000000 -999.000000 -0.986629 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 1.541707 -999.000000 -999.000000 -999.000000 -999.000000 0.083804 -999.000000 -999.000000 -999.000000 -999.000000 -0.227392 -999.000000 -999.000000 -999.000000 -999.000000 -0.741895 -999.000000 -999.000000 -999.000000 -999.000000 -1.492942 -999.000000 -999.000000 -999.000000 -999.000000 -0.118622 -999.000000 -999.000000 -999.000000 -999.000000 0.767655 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.341450 -999.000000 -999.000000 -999.000000 -999.000000 -1.034576 -999.000000 -999.000000 -999.000000 -999.000000 -0.784579 -999.000000 -999.000000 -999.000000 -999.000000 -0.681088 -999.000000 -999.000000 -999.000000 -999.000000 0.355619 -999.000000 -999.000000 -999.000000 -999.000000 1.550881 -999.000000 -999.000000 -999.000000 -999.000000 1.374438 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 diff --git a/pyPDAF/source/example/inputs_online/obs_step11.txt b/pyPDAF/source/example/inputs_online/obs_step11.txt new file mode 100644 index 0000000000000000000000000000000000000000..110ee441505327ead4c2f1e5ab3a1492a6b958ea --- /dev/null +++ b/pyPDAF/source/example/inputs_online/obs_step11.txt @@ -0,0 +1,18 @@ + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -2.185623 -999.000000 -999.000000 -999.000000 -999.000000 -0.825840 -999.000000 -999.000000 -999.000000 -999.000000 -0.118009 -999.000000 -999.000000 -999.000000 -999.000000 1.197515 -999.000000 -999.000000 -999.000000 -999.000000 1.494447 -999.000000 -999.000000 -999.000000 -999.000000 0.898832 -999.000000 -999.000000 -999.000000 -999.000000 -0.850529 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.858246 -999.000000 -999.000000 -999.000000 -999.000000 1.303283 -999.000000 -999.000000 -999.000000 -999.000000 1.073826 -999.000000 -999.000000 -999.000000 -999.000000 -0.061147 -999.000000 -999.000000 -999.000000 -999.000000 -0.944257 -999.000000 -999.000000 -999.000000 -999.000000 -1.035702 -999.000000 -999.000000 -999.000000 -999.000000 -0.367905 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.980795 -999.000000 -999.000000 -999.000000 -999.000000 0.213397 -999.000000 -999.000000 -999.000000 -999.000000 -0.092452 -999.000000 -999.000000 -999.000000 -999.000000 -0.369694 -999.000000 -999.000000 -999.000000 -999.000000 0.056512 -999.000000 -999.000000 -999.000000 -999.000000 -0.624146 -999.000000 -999.000000 -999.000000 -999.000000 0.196723 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.319839 -999.000000 -999.000000 -999.000000 -999.000000 -0.689179 -999.000000 -999.000000 -999.000000 -999.000000 -0.366861 -999.000000 -999.000000 -999.000000 -999.000000 -0.896953 -999.000000 -999.000000 -999.000000 -999.000000 -0.053488 -999.000000 -999.000000 -999.000000 -999.000000 0.412842 -999.000000 -999.000000 -999.000000 -999.000000 1.100695 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 diff --git a/pyPDAF/source/example/inputs_online/obs_step12.txt b/pyPDAF/source/example/inputs_online/obs_step12.txt new file mode 100644 index 0000000000000000000000000000000000000000..df412942bd0b3d83fcd6ec8fa4385b4f5c891c5a --- /dev/null +++ b/pyPDAF/source/example/inputs_online/obs_step12.txt @@ -0,0 +1,18 @@ + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.846399 -999.000000 -999.000000 -999.000000 -999.000000 -0.820365 -999.000000 -999.000000 -999.000000 -999.000000 0.450332 -999.000000 -999.000000 -999.000000 -999.000000 0.253067 -999.000000 -999.000000 -999.000000 -999.000000 0.792666 -999.000000 -999.000000 -999.000000 -999.000000 0.477656 -999.000000 -999.000000 -999.000000 -999.000000 -1.229589 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.159387 -999.000000 -999.000000 -999.000000 -999.000000 0.430819 -999.000000 -999.000000 -999.000000 -999.000000 0.953551 -999.000000 -999.000000 -999.000000 -999.000000 0.720221 -999.000000 -999.000000 -999.000000 -999.000000 -0.241863 -999.000000 -999.000000 -999.000000 -999.000000 -0.264136 -999.000000 -999.000000 -999.000000 -999.000000 -1.052487 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.227073 -999.000000 -999.000000 -999.000000 -999.000000 -0.203736 -999.000000 -999.000000 -999.000000 -999.000000 1.289776 -999.000000 -999.000000 -999.000000 -999.000000 -0.678493 -999.000000 -999.000000 -999.000000 -999.000000 -1.920324 -999.000000 -999.000000 -999.000000 -999.000000 -0.952990 -999.000000 -999.000000 -999.000000 -999.000000 0.233436 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.665620 -999.000000 -999.000000 -999.000000 -999.000000 0.428778 -999.000000 -999.000000 -999.000000 -999.000000 -1.273966 -999.000000 -999.000000 -999.000000 -999.000000 -1.744677 -999.000000 -999.000000 -999.000000 -999.000000 0.241770 -999.000000 -999.000000 -999.000000 -999.000000 0.352905 -999.000000 -999.000000 -999.000000 -999.000000 0.617584 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 diff --git a/pyPDAF/source/example/inputs_online/obs_step13.txt b/pyPDAF/source/example/inputs_online/obs_step13.txt new file mode 100644 index 0000000000000000000000000000000000000000..610ea3db9f05c7f84d018a5a94eac497c0786824 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/obs_step13.txt @@ -0,0 +1,18 @@ + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -1.184244 -999.000000 -999.000000 -999.000000 -999.000000 -0.661184 -999.000000 -999.000000 -999.000000 -999.000000 -0.851309 -999.000000 -999.000000 -999.000000 -999.000000 -0.390333 -999.000000 -999.000000 -999.000000 -999.000000 2.046093 -999.000000 -999.000000 -999.000000 -999.000000 0.773205 -999.000000 -999.000000 -999.000000 -999.000000 0.758894 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -1.132480 -999.000000 -999.000000 -999.000000 -999.000000 -0.803409 -999.000000 -999.000000 -999.000000 -999.000000 0.502843 -999.000000 -999.000000 -999.000000 -999.000000 0.407256 -999.000000 -999.000000 -999.000000 -999.000000 0.324149 -999.000000 -999.000000 -999.000000 -999.000000 -0.242065 -999.000000 -999.000000 -999.000000 -999.000000 -0.498599 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.461356 -999.000000 -999.000000 -999.000000 -999.000000 1.338836 -999.000000 -999.000000 -999.000000 -999.000000 0.709479 -999.000000 -999.000000 -999.000000 -999.000000 0.219055 -999.000000 -999.000000 -999.000000 -999.000000 -0.828386 -999.000000 -999.000000 -999.000000 -999.000000 -0.985630 -999.000000 -999.000000 -999.000000 -999.000000 -1.007326 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 1.058264 -999.000000 -999.000000 -999.000000 -999.000000 -0.223823 -999.000000 -999.000000 -999.000000 -999.000000 -0.242095 -999.000000 -999.000000 -999.000000 -999.000000 -0.766096 -999.000000 -999.000000 -999.000000 -999.000000 -0.265934 -999.000000 -999.000000 -999.000000 -999.000000 0.248291 -999.000000 -999.000000 -999.000000 -999.000000 1.157175 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 diff --git a/pyPDAF/source/example/inputs_online/obs_step14.txt b/pyPDAF/source/example/inputs_online/obs_step14.txt new file mode 100644 index 0000000000000000000000000000000000000000..2e831ed9c1fa0eb6e46dd122f8aeb81e45d8468a --- /dev/null +++ b/pyPDAF/source/example/inputs_online/obs_step14.txt @@ -0,0 +1,18 @@ + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.101095 -999.000000 -999.000000 -999.000000 -999.000000 -0.904790 -999.000000 -999.000000 -999.000000 -999.000000 -1.593171 -999.000000 -999.000000 -999.000000 -999.000000 -0.645719 -999.000000 -999.000000 -999.000000 -999.000000 1.018387 -999.000000 -999.000000 -999.000000 -999.000000 0.945468 -999.000000 -999.000000 -999.000000 -999.000000 0.607797 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.414067 -999.000000 -999.000000 -999.000000 -999.000000 -0.371180 -999.000000 -999.000000 -999.000000 -999.000000 0.149408 -999.000000 -999.000000 -999.000000 -999.000000 1.758621 -999.000000 -999.000000 -999.000000 -999.000000 -0.405404 -999.000000 -999.000000 -999.000000 -999.000000 0.236279 -999.000000 -999.000000 -999.000000 -999.000000 -0.391055 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.139996 -999.000000 -999.000000 -999.000000 -999.000000 0.875425 -999.000000 -999.000000 -999.000000 -999.000000 1.297777 -999.000000 -999.000000 -999.000000 -999.000000 1.011323 -999.000000 -999.000000 -999.000000 -999.000000 -0.378631 -999.000000 -999.000000 -999.000000 -999.000000 -1.265981 -999.000000 -999.000000 -999.000000 -999.000000 -1.002432 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 2.010632 -999.000000 -999.000000 -999.000000 -999.000000 0.241243 -999.000000 -999.000000 -999.000000 -999.000000 -0.315817 -999.000000 -999.000000 -999.000000 -999.000000 -1.188977 -999.000000 -999.000000 -999.000000 -999.000000 -0.368780 -999.000000 -999.000000 -999.000000 -999.000000 -0.110843 -999.000000 -999.000000 -999.000000 -999.000000 0.639159 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 diff --git a/pyPDAF/source/example/inputs_online/obs_step15.txt b/pyPDAF/source/example/inputs_online/obs_step15.txt new file mode 100644 index 0000000000000000000000000000000000000000..af7f6d8de97866887a7dad8e053b804cb8c663e1 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/obs_step15.txt @@ -0,0 +1,18 @@ + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.279289 -999.000000 -999.000000 -999.000000 -999.000000 0.225885 -999.000000 -999.000000 -999.000000 -999.000000 -0.906895 -999.000000 -999.000000 -999.000000 -999.000000 -0.142904 -999.000000 -999.000000 -999.000000 -999.000000 0.396345 -999.000000 -999.000000 -999.000000 -999.000000 0.771619 -999.000000 -999.000000 -999.000000 -999.000000 1.132047 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -1.173595 -999.000000 -999.000000 -999.000000 -999.000000 -0.278410 -999.000000 -999.000000 -999.000000 -999.000000 -0.199923 -999.000000 -999.000000 -999.000000 -999.000000 1.345367 -999.000000 -999.000000 -999.000000 -999.000000 1.685431 -999.000000 -999.000000 -999.000000 -999.000000 1.210061 -999.000000 -999.000000 -999.000000 -999.000000 -1.388787 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.484237 -999.000000 -999.000000 -999.000000 -999.000000 0.756863 -999.000000 -999.000000 -999.000000 -999.000000 0.826549 -999.000000 -999.000000 -999.000000 -999.000000 0.632739 -999.000000 -999.000000 -999.000000 -999.000000 -0.116590 -999.000000 -999.000000 -999.000000 -999.000000 -0.661556 -999.000000 -999.000000 -999.000000 -999.000000 -1.015110 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.449549 -999.000000 -999.000000 -999.000000 -999.000000 0.360570 -999.000000 -999.000000 -999.000000 -999.000000 0.137948 -999.000000 -999.000000 -999.000000 -999.000000 -0.430622 -999.000000 -999.000000 -999.000000 -999.000000 0.273340 -999.000000 -999.000000 -999.000000 -999.000000 -1.673643 -999.000000 -999.000000 -999.000000 -999.000000 0.266328 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 diff --git a/pyPDAF/source/example/inputs_online/obs_step16.txt b/pyPDAF/source/example/inputs_online/obs_step16.txt new file mode 100644 index 0000000000000000000000000000000000000000..9ffed94470ba88100135c2c59f4a1a21573ee312 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/obs_step16.txt @@ -0,0 +1,18 @@ + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.216425 -999.000000 -999.000000 -999.000000 -999.000000 -0.498996 -999.000000 -999.000000 -999.000000 -999.000000 -1.713236 -999.000000 -999.000000 -999.000000 -999.000000 -0.904670 -999.000000 -999.000000 -999.000000 -999.000000 0.383932 -999.000000 -999.000000 -999.000000 -999.000000 1.578359 -999.000000 -999.000000 -999.000000 -999.000000 1.604447 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.982540 -999.000000 -999.000000 -999.000000 -999.000000 -1.303290 -999.000000 -999.000000 -999.000000 -999.000000 -0.386130 -999.000000 -999.000000 -999.000000 -999.000000 1.281995 -999.000000 -999.000000 -999.000000 -999.000000 -0.234739 -999.000000 -999.000000 -999.000000 -999.000000 0.735332 -999.000000 -999.000000 -999.000000 -999.000000 0.238385 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.450487 -999.000000 -999.000000 -999.000000 -999.000000 0.804390 -999.000000 -999.000000 -999.000000 -999.000000 0.536146 -999.000000 -999.000000 -999.000000 -999.000000 1.260156 -999.000000 -999.000000 -999.000000 -999.000000 -0.489508 -999.000000 -999.000000 -999.000000 -999.000000 -0.694493 -999.000000 -999.000000 -999.000000 -999.000000 0.429178 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 1.502297 -999.000000 -999.000000 -999.000000 -999.000000 1.479273 -999.000000 -999.000000 -999.000000 -999.000000 1.184012 -999.000000 -999.000000 -999.000000 -999.000000 -0.913506 -999.000000 -999.000000 -999.000000 -999.000000 -0.740607 -999.000000 -999.000000 -999.000000 -999.000000 -0.995162 -999.000000 -999.000000 -999.000000 -999.000000 -0.752563 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 diff --git a/pyPDAF/source/example/inputs_online/obs_step17.txt b/pyPDAF/source/example/inputs_online/obs_step17.txt new file mode 100644 index 0000000000000000000000000000000000000000..bfd153d6d0c5cb55786995d68852a8fdb46084b6 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/obs_step17.txt @@ -0,0 +1,18 @@ + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.510907 -999.000000 -999.000000 -999.000000 -999.000000 -1.282493 -999.000000 -999.000000 -999.000000 -999.000000 -1.363207 -999.000000 -999.000000 -999.000000 -999.000000 -1.010675 -999.000000 -999.000000 -999.000000 -999.000000 0.631079 -999.000000 -999.000000 -999.000000 -999.000000 -0.134192 -999.000000 -999.000000 -999.000000 -999.000000 0.906210 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -1.381997 -999.000000 -999.000000 -999.000000 -999.000000 -1.352177 -999.000000 -999.000000 -999.000000 -999.000000 -1.256612 -999.000000 -999.000000 -999.000000 -999.000000 0.129934 -999.000000 -999.000000 -999.000000 -999.000000 1.638226 -999.000000 -999.000000 -999.000000 -999.000000 0.153262 -999.000000 -999.000000 -999.000000 -999.000000 0.278367 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.706758 -999.000000 -999.000000 -999.000000 -999.000000 0.155814 -999.000000 -999.000000 -999.000000 -999.000000 1.252619 -999.000000 -999.000000 -999.000000 -999.000000 0.449629 -999.000000 -999.000000 -999.000000 -999.000000 0.665093 -999.000000 -999.000000 -999.000000 -999.000000 -0.202233 -999.000000 -999.000000 -999.000000 -999.000000 -1.178202 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.524264 -999.000000 -999.000000 -999.000000 -999.000000 0.653656 -999.000000 -999.000000 -999.000000 -999.000000 0.535693 -999.000000 -999.000000 -999.000000 -999.000000 -0.519165 -999.000000 -999.000000 -999.000000 -999.000000 -0.928930 -999.000000 -999.000000 -999.000000 -999.000000 -2.147269 -999.000000 -999.000000 -999.000000 -999.000000 -0.883014 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 diff --git a/pyPDAF/source/example/inputs_online/obs_step18.txt b/pyPDAF/source/example/inputs_online/obs_step18.txt new file mode 100644 index 0000000000000000000000000000000000000000..454718c37df49aa5ef812757b1b9f28f0d1fbf1b --- /dev/null +++ b/pyPDAF/source/example/inputs_online/obs_step18.txt @@ -0,0 +1,18 @@ + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.464619 -999.000000 -999.000000 -999.000000 -999.000000 0.626175 -999.000000 -999.000000 -999.000000 -999.000000 -1.171979 -999.000000 -999.000000 -999.000000 -999.000000 -1.462390 -999.000000 -999.000000 -999.000000 -999.000000 -0.341641 -999.000000 -999.000000 -999.000000 -999.000000 -0.729294 -999.000000 -999.000000 -999.000000 -999.000000 0.107625 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.845881 -999.000000 -999.000000 -999.000000 -999.000000 -1.463780 -999.000000 -999.000000 -999.000000 -999.000000 -1.547024 -999.000000 -999.000000 -999.000000 -999.000000 0.570582 -999.000000 -999.000000 -999.000000 -999.000000 -0.422847 -999.000000 -999.000000 -999.000000 -999.000000 0.745573 -999.000000 -999.000000 -999.000000 -999.000000 -0.049335 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -1.520150 -999.000000 -999.000000 -999.000000 -999.000000 -0.307972 -999.000000 -999.000000 -999.000000 -999.000000 1.201617 -999.000000 -999.000000 -999.000000 -999.000000 1.439537 -999.000000 -999.000000 -999.000000 -999.000000 -0.465890 -999.000000 -999.000000 -999.000000 -999.000000 0.421657 -999.000000 -999.000000 -999.000000 -999.000000 -1.329236 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -1.033608 -999.000000 -999.000000 -999.000000 -999.000000 0.204866 -999.000000 -999.000000 -999.000000 -999.000000 1.494976 -999.000000 -999.000000 -999.000000 -999.000000 0.939219 -999.000000 -999.000000 -999.000000 -999.000000 -0.560111 -999.000000 -999.000000 -999.000000 -999.000000 -1.120556 -999.000000 -999.000000 -999.000000 -999.000000 -0.726939 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 diff --git a/pyPDAF/source/example/inputs_online/obs_step2.txt b/pyPDAF/source/example/inputs_online/obs_step2.txt new file mode 100644 index 0000000000000000000000000000000000000000..81df43feaa1513a915c863275d20343762e481dd --- /dev/null +++ b/pyPDAF/source/example/inputs_online/obs_step2.txt @@ -0,0 +1,18 @@ + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.896105 -999.000000 -999.000000 -999.000000 -999.000000 0.345611 -999.000000 -999.000000 -999.000000 -999.000000 -0.083132 -999.000000 -999.000000 -999.000000 -999.000000 -0.464933 -999.000000 -999.000000 -999.000000 -999.000000 -0.842085 -999.000000 -999.000000 -999.000000 -999.000000 -0.112121 -999.000000 -999.000000 -999.000000 -999.000000 1.071802 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.247566 -999.000000 -999.000000 -999.000000 -999.000000 -1.349288 -999.000000 -999.000000 -999.000000 -999.000000 -0.990613 -999.000000 -999.000000 -999.000000 -999.000000 -1.271188 -999.000000 -999.000000 -999.000000 -999.000000 -0.659173 -999.000000 -999.000000 -999.000000 -999.000000 0.328567 -999.000000 -999.000000 -999.000000 -999.000000 1.132107 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -1.638754 -999.000000 -999.000000 -999.000000 -999.000000 -1.016853 -999.000000 -999.000000 -999.000000 -999.000000 -0.333591 -999.000000 -999.000000 -999.000000 -999.000000 1.538253 -999.000000 -999.000000 -999.000000 -999.000000 1.728074 -999.000000 -999.000000 -999.000000 -999.000000 0.516225 -999.000000 -999.000000 -999.000000 -999.000000 0.152963 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.286199 -999.000000 -999.000000 -999.000000 -999.000000 -0.139595 -999.000000 -999.000000 -999.000000 -999.000000 0.490703 -999.000000 -999.000000 -999.000000 -999.000000 1.632924 -999.000000 -999.000000 -999.000000 -999.000000 0.549396 -999.000000 -999.000000 -999.000000 -999.000000 -1.067022 -999.000000 -999.000000 -999.000000 -999.000000 -1.224152 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 diff --git a/pyPDAF/source/example/inputs_online/obs_step3.txt b/pyPDAF/source/example/inputs_online/obs_step3.txt new file mode 100644 index 0000000000000000000000000000000000000000..8abdf0c5a641a4da5a0f22cb185fd2364878ef8c --- /dev/null +++ b/pyPDAF/source/example/inputs_online/obs_step3.txt @@ -0,0 +1,18 @@ + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 1.083209 -999.000000 -999.000000 -999.000000 -999.000000 0.433738 -999.000000 -999.000000 -999.000000 -999.000000 1.075180 -999.000000 -999.000000 -999.000000 -999.000000 -0.378655 -999.000000 -999.000000 -999.000000 -999.000000 -1.065424 -999.000000 -999.000000 -999.000000 -999.000000 -0.413697 -999.000000 -999.000000 -999.000000 -999.000000 0.956990 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.449111 -999.000000 -999.000000 -999.000000 -999.000000 -0.404926 -999.000000 -999.000000 -999.000000 -999.000000 -2.194094 -999.000000 -999.000000 -999.000000 -999.000000 -1.273953 -999.000000 -999.000000 -999.000000 -999.000000 -0.517423 -999.000000 -999.000000 -999.000000 -999.000000 0.707362 -999.000000 -999.000000 -999.000000 -999.000000 0.801232 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.804001 -999.000000 -999.000000 -999.000000 -999.000000 -0.973386 -999.000000 -999.000000 -999.000000 -999.000000 -0.780164 -999.000000 -999.000000 -999.000000 -999.000000 0.155640 -999.000000 -999.000000 -999.000000 -999.000000 1.003887 -999.000000 -999.000000 -999.000000 -999.000000 1.164193 -999.000000 -999.000000 -999.000000 -999.000000 0.821222 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -1.255145 -999.000000 -999.000000 -999.000000 -999.000000 0.214995 -999.000000 -999.000000 -999.000000 -999.000000 0.366347 -999.000000 -999.000000 -999.000000 -999.000000 0.738899 -999.000000 -999.000000 -999.000000 -999.000000 0.481009 -999.000000 -999.000000 -999.000000 -999.000000 -0.345166 -999.000000 -999.000000 -999.000000 -999.000000 -1.268341 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 diff --git a/pyPDAF/source/example/inputs_online/obs_step4.txt b/pyPDAF/source/example/inputs_online/obs_step4.txt new file mode 100644 index 0000000000000000000000000000000000000000..d15badbfbf4685c21c474a22e02d54b03adcb614 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/obs_step4.txt @@ -0,0 +1,18 @@ + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 1.556819 -999.000000 -999.000000 -999.000000 -999.000000 1.692076 -999.000000 -999.000000 -999.000000 -999.000000 0.713348 -999.000000 -999.000000 -999.000000 -999.000000 -1.474017 -999.000000 -999.000000 -999.000000 -999.000000 -0.478775 -999.000000 -999.000000 -999.000000 -999.000000 0.194569 -999.000000 -999.000000 -999.000000 -999.000000 0.214266 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.117359 -999.000000 -999.000000 -999.000000 -999.000000 0.703804 -999.000000 -999.000000 -999.000000 -999.000000 -0.269491 -999.000000 -999.000000 -999.000000 -999.000000 -1.984577 -999.000000 -999.000000 -999.000000 -999.000000 -0.121921 -999.000000 -999.000000 -999.000000 -999.000000 0.281131 -999.000000 -999.000000 -999.000000 -999.000000 0.651114 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.674735 -999.000000 -999.000000 -999.000000 -999.000000 -0.318449 -999.000000 -999.000000 -999.000000 -999.000000 -0.653992 -999.000000 -999.000000 -999.000000 -999.000000 -0.081376 -999.000000 -999.000000 -999.000000 -999.000000 0.513642 -999.000000 -999.000000 -999.000000 -999.000000 0.719125 -999.000000 -999.000000 -999.000000 -999.000000 0.972788 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -1.139349 -999.000000 -999.000000 -999.000000 -999.000000 -0.228347 -999.000000 -999.000000 -999.000000 -999.000000 1.223513 -999.000000 -999.000000 -999.000000 -999.000000 1.571211 -999.000000 -999.000000 -999.000000 -999.000000 0.631126 -999.000000 -999.000000 -999.000000 -999.000000 0.518420 -999.000000 -999.000000 -999.000000 -999.000000 -0.771967 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 diff --git a/pyPDAF/source/example/inputs_online/obs_step5.txt b/pyPDAF/source/example/inputs_online/obs_step5.txt new file mode 100644 index 0000000000000000000000000000000000000000..26a3de0fea225fe10418111189f2545d9625f6c1 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/obs_step5.txt @@ -0,0 +1,18 @@ + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.801726 -999.000000 -999.000000 -999.000000 -999.000000 0.674836 -999.000000 -999.000000 -999.000000 -999.000000 0.607346 -999.000000 -999.000000 -999.000000 -999.000000 0.487122 -999.000000 -999.000000 -999.000000 -999.000000 -0.979706 -999.000000 -999.000000 -999.000000 -999.000000 -0.510762 -999.000000 -999.000000 -999.000000 -999.000000 -0.000708 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 1.339587 -999.000000 -999.000000 -999.000000 -999.000000 0.214655 -999.000000 -999.000000 -999.000000 -999.000000 -0.789001 -999.000000 -999.000000 -999.000000 -999.000000 -1.220432 -999.000000 -999.000000 -999.000000 -999.000000 -1.083815 -999.000000 -999.000000 -999.000000 -999.000000 -0.008010 -999.000000 -999.000000 -999.000000 -999.000000 1.421907 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.275466 -999.000000 -999.000000 -999.000000 -999.000000 -0.960556 -999.000000 -999.000000 -999.000000 -999.000000 -1.762772 -999.000000 -999.000000 -999.000000 -999.000000 -0.253507 -999.000000 -999.000000 -999.000000 -999.000000 -0.462122 -999.000000 -999.000000 -999.000000 -999.000000 1.208648 -999.000000 -999.000000 -999.000000 -999.000000 0.647535 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.649653 -999.000000 -999.000000 -999.000000 -999.000000 -0.091477 -999.000000 -999.000000 -999.000000 -999.000000 0.561350 -999.000000 -999.000000 -999.000000 -999.000000 1.149089 -999.000000 -999.000000 -999.000000 -999.000000 0.968397 -999.000000 -999.000000 -999.000000 -999.000000 -0.320283 -999.000000 -999.000000 -999.000000 -999.000000 0.332012 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 diff --git a/pyPDAF/source/example/inputs_online/obs_step6.txt b/pyPDAF/source/example/inputs_online/obs_step6.txt new file mode 100644 index 0000000000000000000000000000000000000000..7c14bb0aa6c6ad47110ca9156f638cc86a358d43 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/obs_step6.txt @@ -0,0 +1,18 @@ + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.653417 -999.000000 -999.000000 -999.000000 -999.000000 1.133325 -999.000000 -999.000000 -999.000000 -999.000000 1.057432 -999.000000 -999.000000 -999.000000 -999.000000 -0.020721 -999.000000 -999.000000 -999.000000 -999.000000 0.337863 -999.000000 -999.000000 -999.000000 -999.000000 -0.038440 -999.000000 -999.000000 -999.000000 -999.000000 -0.295972 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.653431 -999.000000 -999.000000 -999.000000 -999.000000 0.877542 -999.000000 -999.000000 -999.000000 -999.000000 0.582615 -999.000000 -999.000000 -999.000000 -999.000000 -0.629781 -999.000000 -999.000000 -999.000000 -999.000000 -0.689564 -999.000000 -999.000000 -999.000000 -999.000000 -0.749559 -999.000000 -999.000000 -999.000000 -999.000000 0.763884 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.629187 -999.000000 -999.000000 -999.000000 -999.000000 -0.645544 -999.000000 -999.000000 -999.000000 -999.000000 -1.004383 -999.000000 -999.000000 -999.000000 -999.000000 -0.690036 -999.000000 -999.000000 -999.000000 -999.000000 1.035050 -999.000000 -999.000000 -999.000000 -999.000000 1.164238 -999.000000 -999.000000 -999.000000 -999.000000 1.566723 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -1.495882 -999.000000 -999.000000 -999.000000 -999.000000 -0.649314 -999.000000 -999.000000 -999.000000 -999.000000 -0.134699 -999.000000 -999.000000 -999.000000 -999.000000 2.179924 -999.000000 -999.000000 -999.000000 -999.000000 1.417198 -999.000000 -999.000000 -999.000000 -999.000000 0.219324 -999.000000 -999.000000 -999.000000 -999.000000 0.813706 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 diff --git a/pyPDAF/source/example/inputs_online/obs_step7.txt b/pyPDAF/source/example/inputs_online/obs_step7.txt new file mode 100644 index 0000000000000000000000000000000000000000..0eb9e87955723bda9fe5cfe8930a6655736a11c6 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/obs_step7.txt @@ -0,0 +1,18 @@ + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.733103 -999.000000 -999.000000 -999.000000 -999.000000 0.766897 -999.000000 -999.000000 -999.000000 -999.000000 0.774590 -999.000000 -999.000000 -999.000000 -999.000000 0.429608 -999.000000 -999.000000 -999.000000 -999.000000 -0.272822 -999.000000 -999.000000 -999.000000 -999.000000 -0.236091 -999.000000 -999.000000 -999.000000 -999.000000 -0.675033 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.983378 -999.000000 -999.000000 -999.000000 -999.000000 0.204653 -999.000000 -999.000000 -999.000000 -999.000000 0.353663 -999.000000 -999.000000 -999.000000 -999.000000 -0.483646 -999.000000 -999.000000 -999.000000 -999.000000 -1.921564 -999.000000 -999.000000 -999.000000 -999.000000 -0.370235 -999.000000 -999.000000 -999.000000 -999.000000 0.098615 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.966806 -999.000000 -999.000000 -999.000000 -999.000000 -1.042963 -999.000000 -999.000000 -999.000000 -999.000000 -0.537529 -999.000000 -999.000000 -999.000000 -999.000000 -0.209907 -999.000000 -999.000000 -999.000000 -999.000000 0.101543 -999.000000 -999.000000 -999.000000 -999.000000 -0.667224 -999.000000 -999.000000 -999.000000 -999.000000 1.764526 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.592910 -999.000000 -999.000000 -999.000000 -999.000000 -0.802009 -999.000000 -999.000000 -999.000000 -999.000000 -0.247423 -999.000000 -999.000000 -999.000000 -999.000000 0.930429 -999.000000 -999.000000 -999.000000 -999.000000 1.472646 -999.000000 -999.000000 -999.000000 -999.000000 0.605407 -999.000000 -999.000000 -999.000000 -999.000000 0.363822 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 diff --git a/pyPDAF/source/example/inputs_online/obs_step8.txt b/pyPDAF/source/example/inputs_online/obs_step8.txt new file mode 100644 index 0000000000000000000000000000000000000000..1afe34347200462e556fc6ff5f010293653a88ec --- /dev/null +++ b/pyPDAF/source/example/inputs_online/obs_step8.txt @@ -0,0 +1,18 @@ + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.660137 -999.000000 -999.000000 -999.000000 -999.000000 0.426189 -999.000000 -999.000000 -999.000000 -999.000000 1.216357 -999.000000 -999.000000 -999.000000 -999.000000 1.302422 -999.000000 -999.000000 -999.000000 -999.000000 -0.168279 -999.000000 -999.000000 -999.000000 -999.000000 -0.887508 -999.000000 -999.000000 -999.000000 -999.000000 -1.645647 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 1.290148 -999.000000 -999.000000 -999.000000 -999.000000 1.158181 -999.000000 -999.000000 -999.000000 -999.000000 0.028303 -999.000000 -999.000000 -999.000000 -999.000000 -0.296412 -999.000000 -999.000000 -999.000000 -999.000000 -0.576271 -999.000000 -999.000000 -999.000000 -999.000000 -0.472041 -999.000000 -999.000000 -999.000000 -999.000000 0.411081 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.852419 -999.000000 -999.000000 -999.000000 -999.000000 -0.235932 -999.000000 -999.000000 -999.000000 -999.000000 -0.927618 -999.000000 -999.000000 -999.000000 -999.000000 -0.310022 -999.000000 -999.000000 -999.000000 -999.000000 -0.335753 -999.000000 -999.000000 -999.000000 -999.000000 0.320617 -999.000000 -999.000000 -999.000000 -999.000000 0.491461 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.187963 -999.000000 -999.000000 -999.000000 -999.000000 -1.061163 -999.000000 -999.000000 -999.000000 -999.000000 -1.722883 -999.000000 -999.000000 -999.000000 -999.000000 0.210534 -999.000000 -999.000000 -999.000000 -999.000000 1.107916 -999.000000 -999.000000 -999.000000 -999.000000 0.521436 -999.000000 -999.000000 -999.000000 -999.000000 0.915162 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 diff --git a/pyPDAF/source/example/inputs_online/obs_step9.txt b/pyPDAF/source/example/inputs_online/obs_step9.txt new file mode 100644 index 0000000000000000000000000000000000000000..a574256b9debb136b56eb38a4f74c600a3f996ed --- /dev/null +++ b/pyPDAF/source/example/inputs_online/obs_step9.txt @@ -0,0 +1,18 @@ + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.112336 -999.000000 -999.000000 -999.000000 -999.000000 -0.319578 -999.000000 -999.000000 -999.000000 -999.000000 1.328895 -999.000000 -999.000000 -999.000000 -999.000000 0.529090 -999.000000 -999.000000 -999.000000 -999.000000 0.800282 -999.000000 -999.000000 -999.000000 -999.000000 0.716336 -999.000000 -999.000000 -999.000000 -999.000000 -1.797716 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.423227 -999.000000 -999.000000 -999.000000 -999.000000 1.313680 -999.000000 -999.000000 -999.000000 -999.000000 -0.055959 -999.000000 -999.000000 -999.000000 -999.000000 -0.405170 -999.000000 -999.000000 -999.000000 -999.000000 -0.501037 -999.000000 -999.000000 -999.000000 -999.000000 -0.935483 -999.000000 -999.000000 -999.000000 -999.000000 -0.042825 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 0.219795 -999.000000 -999.000000 -999.000000 -999.000000 0.983546 -999.000000 -999.000000 -999.000000 -999.000000 -0.818541 -999.000000 -999.000000 -999.000000 -999.000000 -0.571304 -999.000000 -999.000000 -999.000000 -999.000000 -0.058828 -999.000000 -999.000000 -999.000000 -999.000000 -0.814005 -999.000000 -999.000000 -999.000000 -999.000000 0.738519 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -0.071815 -999.000000 -999.000000 -999.000000 -999.000000 -1.376153 -999.000000 -999.000000 -999.000000 -999.000000 -0.564014 -999.000000 -999.000000 -999.000000 -999.000000 -0.721464 -999.000000 -999.000000 -999.000000 -999.000000 0.881649 -999.000000 -999.000000 -999.000000 -999.000000 0.823219 -999.000000 -999.000000 -999.000000 -999.000000 0.416711 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 + -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 -999.000000 diff --git a/pyPDAF/source/example/inputs_online/state_ini.txt b/pyPDAF/source/example/inputs_online/state_ini.txt new file mode 100644 index 0000000000000000000000000000000000000000..df71b8f000ed5a69afa3507b3593352022ba5199 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/state_ini.txt @@ -0,0 +1,18 @@ + -0.490164 -0.554138 -0.601275 -0.630142 -0.639863 -0.630142 -0.601275 -0.554138 -0.490164 -0.411296 -0.319932 -0.218846 -0.111111 -0.000000 0.111111 0.218846 0.319932 0.411296 0.490164 0.554138 0.601275 0.630142 0.639863 0.630142 0.601275 0.554138 0.490164 0.411296 0.319932 0.218846 0.111111 0.000000 -0.111111 -0.218846 -0.319932 -0.411296 + -0.601275 -0.630142 -0.639863 -0.630142 -0.601275 -0.554138 -0.490164 -0.411296 -0.319932 -0.218846 -0.111111 -0.000000 0.111111 0.218846 0.319932 0.411296 0.490164 0.554138 0.601275 0.630142 0.639863 0.630142 0.601275 0.554138 0.490164 0.411296 0.319932 0.218846 0.111111 0.000000 -0.111111 -0.218846 -0.319932 -0.411296 -0.490164 -0.554138 + -0.639863 -0.630142 -0.601275 -0.554138 -0.490164 -0.411296 -0.319932 -0.218846 -0.111111 -0.000000 0.111111 0.218846 0.319932 0.411296 0.490164 0.554138 0.601275 0.630142 0.639863 0.630142 0.601275 0.554138 0.490164 0.411296 0.319932 0.218846 0.111111 0.000000 -0.111111 -0.218846 -0.319932 -0.411296 -0.490164 -0.554138 -0.601275 -0.630142 + -0.601275 -0.554138 -0.490164 -0.411296 -0.319932 -0.218846 -0.111111 -0.000000 0.111111 0.218846 0.319932 0.411296 0.490164 0.554138 0.601275 0.630142 0.639863 0.630142 0.601275 0.554138 0.490164 0.411296 0.319932 0.218846 0.111111 0.000000 -0.111111 -0.218846 -0.319932 -0.411296 -0.490164 -0.554138 -0.601275 -0.630142 -0.639863 -0.630142 + -0.490164 -0.411296 -0.319932 -0.218846 -0.111111 -0.000000 0.111111 0.218846 0.319932 0.411296 0.490164 0.554138 0.601275 0.630142 0.639863 0.630142 0.601275 0.554138 0.490164 0.411296 0.319932 0.218846 0.111111 0.000000 -0.111111 -0.218846 -0.319932 -0.411296 -0.490164 -0.554138 -0.601275 -0.630142 -0.639863 -0.630142 -0.601275 -0.554138 + -0.319932 -0.218846 -0.111111 -0.000000 0.111111 0.218846 0.319932 0.411296 0.490164 0.554138 0.601275 0.630142 0.639863 0.630142 0.601275 0.554138 0.490164 0.411296 0.319932 0.218846 0.111111 0.000000 -0.111111 -0.218846 -0.319932 -0.411296 -0.490164 -0.554138 -0.601275 -0.630142 -0.639863 -0.630142 -0.601275 -0.554138 -0.490164 -0.411296 + -0.111111 -0.000000 0.111111 0.218846 0.319932 0.411296 0.490164 0.554138 0.601275 0.630142 0.639863 0.630142 0.601275 0.554138 0.490164 0.411296 0.319932 0.218846 0.111111 0.000000 -0.111111 -0.218846 -0.319932 -0.411296 -0.490164 -0.554138 -0.601275 -0.630142 -0.639863 -0.630142 -0.601275 -0.554138 -0.490164 -0.411296 -0.319932 -0.218846 + 0.111111 0.218846 0.319932 0.411296 0.490164 0.554138 0.601275 0.630142 0.639863 0.630142 0.601275 0.554138 0.490164 0.411296 0.319932 0.218846 0.111111 0.000000 -0.111111 -0.218846 -0.319932 -0.411296 -0.490164 -0.554138 -0.601275 -0.630142 -0.639863 -0.630142 -0.601275 -0.554138 -0.490164 -0.411296 -0.319932 -0.218846 -0.111111 -0.000000 + 0.319932 0.411296 0.490164 0.554138 0.601275 0.630142 0.639863 0.630142 0.601275 0.554138 0.490164 0.411296 0.319932 0.218846 0.111111 0.000000 -0.111111 -0.218846 -0.319932 -0.411296 -0.490164 -0.554138 -0.601275 -0.630142 -0.639863 -0.630142 -0.601275 -0.554138 -0.490164 -0.411296 -0.319932 -0.218846 -0.111111 -0.000000 0.111111 0.218846 + 0.490164 0.554138 0.601275 0.630142 0.639863 0.630142 0.601275 0.554138 0.490164 0.411296 0.319932 0.218846 0.111111 0.000000 -0.111111 -0.218846 -0.319932 -0.411296 -0.490164 -0.554138 -0.601275 -0.630142 -0.639863 -0.630142 -0.601275 -0.554138 -0.490164 -0.411296 -0.319932 -0.218846 -0.111111 -0.000000 0.111111 0.218846 0.319932 0.411296 + 0.601275 0.630142 0.639863 0.630142 0.601275 0.554138 0.490164 0.411296 0.319932 0.218846 0.111111 0.000000 -0.111111 -0.218846 -0.319932 -0.411296 -0.490164 -0.554138 -0.601275 -0.630142 -0.639863 -0.630142 -0.601275 -0.554138 -0.490164 -0.411296 -0.319932 -0.218846 -0.111111 -0.000000 0.111111 0.218846 0.319932 0.411296 0.490164 0.554138 + 0.639863 0.630142 0.601275 0.554138 0.490164 0.411296 0.319932 0.218846 0.111111 0.000000 -0.111111 -0.218846 -0.319932 -0.411296 -0.490164 -0.554138 -0.601275 -0.630142 -0.639863 -0.630142 -0.601275 -0.554138 -0.490164 -0.411296 -0.319932 -0.218846 -0.111111 -0.000000 0.111111 0.218846 0.319932 0.411296 0.490164 0.554138 0.601275 0.630142 + 0.601275 0.554138 0.490164 0.411296 0.319932 0.218846 0.111111 0.000000 -0.111111 -0.218846 -0.319932 -0.411296 -0.490164 -0.554138 -0.601275 -0.630142 -0.639863 -0.630142 -0.601275 -0.554138 -0.490164 -0.411296 -0.319932 -0.218846 -0.111111 -0.000000 0.111111 0.218846 0.319932 0.411296 0.490164 0.554138 0.601275 0.630142 0.639863 0.630142 + 0.490164 0.411296 0.319932 0.218846 0.111111 0.000000 -0.111111 -0.218846 -0.319932 -0.411296 -0.490164 -0.554138 -0.601275 -0.630142 -0.639863 -0.630142 -0.601275 -0.554138 -0.490164 -0.411296 -0.319932 -0.218846 -0.111111 -0.000000 0.111111 0.218846 0.319932 0.411296 0.490164 0.554138 0.601275 0.630142 0.639863 0.630142 0.601275 0.554138 + 0.319932 0.218846 0.111111 0.000000 -0.111111 -0.218846 -0.319932 -0.411296 -0.490164 -0.554138 -0.601275 -0.630142 -0.639863 -0.630142 -0.601275 -0.554138 -0.490164 -0.411296 -0.319932 -0.218846 -0.111111 -0.000000 0.111111 0.218846 0.319932 0.411296 0.490164 0.554138 0.601275 0.630142 0.639863 0.630142 0.601275 0.554138 0.490164 0.411296 + 0.111111 0.000000 -0.111111 -0.218846 -0.319932 -0.411296 -0.490164 -0.554138 -0.601275 -0.630142 -0.639863 -0.630142 -0.601275 -0.554138 -0.490164 -0.411296 -0.319932 -0.218846 -0.111111 -0.000000 0.111111 0.218846 0.319932 0.411296 0.490164 0.554138 0.601275 0.630142 0.639863 0.630142 0.601275 0.554138 0.490164 0.411296 0.319932 0.218846 + -0.111111 -0.218846 -0.319932 -0.411296 -0.490164 -0.554138 -0.601275 -0.630142 -0.639863 -0.630142 -0.601275 -0.554138 -0.490164 -0.411296 -0.319932 -0.218846 -0.111111 -0.000000 0.111111 0.218846 0.319932 0.411296 0.490164 0.554138 0.601275 0.630142 0.639863 0.630142 0.601275 0.554138 0.490164 0.411296 0.319932 0.218846 0.111111 0.000000 + -0.319932 -0.411296 -0.490164 -0.554138 -0.601275 -0.630142 -0.639863 -0.630142 -0.601275 -0.554138 -0.490164 -0.411296 -0.319932 -0.218846 -0.111111 -0.000000 0.111111 0.218846 0.319932 0.411296 0.490164 0.554138 0.601275 0.630142 0.639863 0.630142 0.601275 0.554138 0.490164 0.411296 0.319932 0.218846 0.111111 0.000000 -0.111111 -0.218846 diff --git a/pyPDAF/source/example/inputs_online/true_initial.txt b/pyPDAF/source/example/inputs_online/true_initial.txt new file mode 100644 index 0000000000000000000000000000000000000000..08ed8778108c55cef398265baab8d84e9c26cdcd --- /dev/null +++ b/pyPDAF/source/example/inputs_online/true_initial.txt @@ -0,0 +1,18 @@ + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 diff --git a/pyPDAF/source/example/inputs_online/true_step1.txt b/pyPDAF/source/example/inputs_online/true_step1.txt new file mode 100644 index 0000000000000000000000000000000000000000..e6638f0453d4ad319e8296950724ee2043d6305c --- /dev/null +++ b/pyPDAF/source/example/inputs_online/true_step1.txt @@ -0,0 +1,18 @@ + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 diff --git a/pyPDAF/source/example/inputs_online/true_step10.txt b/pyPDAF/source/example/inputs_online/true_step10.txt new file mode 100644 index 0000000000000000000000000000000000000000..5be8b182ff3b1380ea3f315658f11b4cda85d23a --- /dev/null +++ b/pyPDAF/source/example/inputs_online/true_step10.txt @@ -0,0 +1,18 @@ + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 diff --git a/pyPDAF/source/example/inputs_online/true_step11.txt b/pyPDAF/source/example/inputs_online/true_step11.txt new file mode 100644 index 0000000000000000000000000000000000000000..db911471da892c730d79e2ad5c03fab459dd4aff --- /dev/null +++ b/pyPDAF/source/example/inputs_online/true_step11.txt @@ -0,0 +1,18 @@ + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 diff --git a/pyPDAF/source/example/inputs_online/true_step12.txt b/pyPDAF/source/example/inputs_online/true_step12.txt new file mode 100644 index 0000000000000000000000000000000000000000..549c410499142bc5e69facb38b0804ee37867244 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/true_step12.txt @@ -0,0 +1,18 @@ + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 diff --git a/pyPDAF/source/example/inputs_online/true_step13.txt b/pyPDAF/source/example/inputs_online/true_step13.txt new file mode 100644 index 0000000000000000000000000000000000000000..4350d588b570e514006e95a6cfec81dd0cf0b86d --- /dev/null +++ b/pyPDAF/source/example/inputs_online/true_step13.txt @@ -0,0 +1,18 @@ + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 diff --git a/pyPDAF/source/example/inputs_online/true_step14.txt b/pyPDAF/source/example/inputs_online/true_step14.txt new file mode 100644 index 0000000000000000000000000000000000000000..89e34e74d880663b3c9a102fefb99f9e051d2489 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/true_step14.txt @@ -0,0 +1,18 @@ + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 diff --git a/pyPDAF/source/example/inputs_online/true_step15.txt b/pyPDAF/source/example/inputs_online/true_step15.txt new file mode 100644 index 0000000000000000000000000000000000000000..4839dee3befadefd6ffe214451f7df3ba40b2e37 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/true_step15.txt @@ -0,0 +1,18 @@ + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 diff --git a/pyPDAF/source/example/inputs_online/true_step16.txt b/pyPDAF/source/example/inputs_online/true_step16.txt new file mode 100644 index 0000000000000000000000000000000000000000..467eb76157889ccb36a5084de45d608e69ee98b7 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/true_step16.txt @@ -0,0 +1,18 @@ + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 diff --git a/pyPDAF/source/example/inputs_online/true_step17.txt b/pyPDAF/source/example/inputs_online/true_step17.txt new file mode 100644 index 0000000000000000000000000000000000000000..ceaa158b1a325eb29bb35046ad709265d84d1e10 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/true_step17.txt @@ -0,0 +1,18 @@ + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 diff --git a/pyPDAF/source/example/inputs_online/true_step18.txt b/pyPDAF/source/example/inputs_online/true_step18.txt new file mode 100644 index 0000000000000000000000000000000000000000..08ed8778108c55cef398265baab8d84e9c26cdcd --- /dev/null +++ b/pyPDAF/source/example/inputs_online/true_step18.txt @@ -0,0 +1,18 @@ + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 diff --git a/pyPDAF/source/example/inputs_online/true_step2.txt b/pyPDAF/source/example/inputs_online/true_step2.txt new file mode 100644 index 0000000000000000000000000000000000000000..29278bc169ab3a35749268b7c0fb36dab579fbfc --- /dev/null +++ b/pyPDAF/source/example/inputs_online/true_step2.txt @@ -0,0 +1,18 @@ + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 diff --git a/pyPDAF/source/example/inputs_online/true_step3.txt b/pyPDAF/source/example/inputs_online/true_step3.txt new file mode 100644 index 0000000000000000000000000000000000000000..725f6a44a695c64ed8e119f6a0f356ce42951ef6 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/true_step3.txt @@ -0,0 +1,18 @@ + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 diff --git a/pyPDAF/source/example/inputs_online/true_step4.txt b/pyPDAF/source/example/inputs_online/true_step4.txt new file mode 100644 index 0000000000000000000000000000000000000000..88389e7b3e1de56927cb099995ef6e459c1c7ce5 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/true_step4.txt @@ -0,0 +1,18 @@ + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 diff --git a/pyPDAF/source/example/inputs_online/true_step5.txt b/pyPDAF/source/example/inputs_online/true_step5.txt new file mode 100644 index 0000000000000000000000000000000000000000..b50375d66ec0ed4426196d4866505e7f85b106a0 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/true_step5.txt @@ -0,0 +1,18 @@ + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 diff --git a/pyPDAF/source/example/inputs_online/true_step6.txt b/pyPDAF/source/example/inputs_online/true_step6.txt new file mode 100644 index 0000000000000000000000000000000000000000..ea4a2cf25d4630b57b82bf3bf506bea64def7ff6 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/true_step6.txt @@ -0,0 +1,18 @@ + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 diff --git a/pyPDAF/source/example/inputs_online/true_step7.txt b/pyPDAF/source/example/inputs_online/true_step7.txt new file mode 100644 index 0000000000000000000000000000000000000000..86ed2982ec6cb30b4fd8f8e2b62ad29ba331197b --- /dev/null +++ b/pyPDAF/source/example/inputs_online/true_step7.txt @@ -0,0 +1,18 @@ + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 diff --git a/pyPDAF/source/example/inputs_online/true_step8.txt b/pyPDAF/source/example/inputs_online/true_step8.txt new file mode 100644 index 0000000000000000000000000000000000000000..7170ccf8d81553d076001b39e693e04ccd597cb4 --- /dev/null +++ b/pyPDAF/source/example/inputs_online/true_step8.txt @@ -0,0 +1,18 @@ + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 diff --git a/pyPDAF/source/example/inputs_online/true_step9.txt b/pyPDAF/source/example/inputs_online/true_step9.txt new file mode 100644 index 0000000000000000000000000000000000000000..3bdd4570360f5b1b5890ae62c4970b25100ae6bd --- /dev/null +++ b/pyPDAF/source/example/inputs_online/true_step9.txt @@ -0,0 +1,18 @@ + -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 + -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 + -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 + -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 + -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 + -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 + -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 + -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 + 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 + 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 + 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 + 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 + 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 + 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 + 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 + 0.50000000 0.34202014 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 + 0.17364818 0.00000000 -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 + -0.17364818 -0.34202014 -0.50000000 -0.64278761 -0.76604444 -0.86602540 -0.93969262 -0.98480775 -1.00000000 -0.98480775 -0.93969262 -0.86602540 -0.76604444 -0.64278761 -0.50000000 -0.34202014 -0.17364818 -0.00000000 0.17364818 0.34202014 0.50000000 0.64278761 0.76604444 0.86602540 0.93969262 0.98480775 1.00000000 0.98480775 0.93969262 0.86602540 0.76604444 0.64278761 0.50000000 0.34202014 0.17364818 0.00000000 diff --git a/pyPDAF/source/example/offline/collector.py b/pyPDAF/source/example/offline/collector.py new file mode 100644 index 0000000000000000000000000000000000000000..78345b9bed1b8f3a54600a729c281c8553ee8b63 --- /dev/null +++ b/pyPDAF/source/example/offline/collector.py @@ -0,0 +1,76 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import numpy as np + +import config +import model +import parallelisation + + +class Collector: + """Here, the background/forecast ensemble is read from files. + + Attributes + ---------- + model: model.model_grid + model instance + """ + def __init__(self, model_grid:model.ModelGrid, + pe: parallelisation.Parallelisation) -> None: + # initialise the model instance + self.model_grid: model.ModelGrid = model_grid + self.pe: parallelisation.Parallelisation = pe + + def init_ens_pdaf(self, _filtertype:int, _dim_p:int, dim_ens:int, + state_p:np.ndarray, uinv:np.ndarray, ens_p:np.ndarray, + status_pdaf:int) -> tuple[np.ndarray, np.ndarray, np.ndarray, int]: + """read forecast ensemble for DA + + In offline DA, the ensemble is read from disk. + One does not need collect/distribute ensemble to model. + + Parameters + ---------- + filtertype: int + filter type + dim_p: int + dimension of state vector on local processor + dim_ens: int + ensemble size + state_p: np.ndarray + state vector on local processor + uinv: np.ndarray + inverse of of + ens_p: np.ndarray + ensemble matrix on local processor + """ + # The initial ensemble is read here and will be distributed to + # the model in the PDAF.get_state functtion by a distributor. + + # If your ensemble is read from a restart file, you can simply set this + # function as a dummy function without doing anything + # However, you still need to set a distributor to call PDAF.get_state, which + # does nothing as well. + nx_p:int = self.model_grid.nx_p + offset:int = self.pe.mype_filter*nx_p + for i in range(dim_ens): + ens_p[:, i] = np.loadtxt( + config.init_ens_path.format(i=i+1) + )[:, offset:offset+nx_p].ravel() + return state_p, uinv, ens_p, status_pdaf diff --git a/pyPDAF/source/example/offline/config.py b/pyPDAF/source/example/offline/config.py new file mode 100644 index 0000000000000000000000000000000000000000..751b6aff274651d28df87bc031bfe970b3d1f962 --- /dev/null +++ b/pyPDAF/source/example/offline/config.py @@ -0,0 +1,93 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This is a template file for PDAF configurations. + +The module can be modified to be adjusted to read configparser/YAML/JSON etc. to initialise +options in PDAF and the DA system. +""" +import os + + +# verbosity of the PDAF screen output +screen:int = 2 + +### Filepath ### +# path to initial ensemble, the filename is formatted for different time step +# here a relative path is given +init_ens_path:str = os.path.join('inputs_offline', 'ens_{i}.txt') +# path to initial truth +init_truth_path:str = os.path.join('inputs_offline', 'true.txt') + +#### Model configurations #### +# number of grid points in x-direction +nx = 36 +# number of grid points in y-direction +ny = 18 +# initial time step +init_step = 0 +# total number of time steps +nsteps:int = 19 + +#### filter options #### +# number of ensemble members +dim_ens:int = 4 +# the type of filter used +# 1=SEIK, 2=EnKF, 3=LSEIK, 4=ETKF, 5=LETKF, 6=ESTKF, 7=LESTKF +# 8=LEnKF, 9=NETF, 10=LNETF, 11=LKNETF, 12=PF, 100=GENOBS, +# 200=3DVar, 0=SEEK +# For a simplified documentation, see:https://pdaf.awi.de/trac/wiki/AvailableOptionsforInitPDAF +# Different DA scheme requires different user-supplied functions +# More information can be found in the PDAF documentation +filtertype:int = 7 +# Variants of each DA scheme check https://pdaf.awi.de/trac/wiki/AvailableOptionsforInitPDAF +subtype:int = 0 +# type of forgetting factor +# - (0) fixed +# - (1) global adaptive +# - (2) local adaptive for LSEIK/LETKF/LESTKF +type_forget:int = 0 +# forgetting factor +forget:float = 1.0 + +#### transformation-related options for Kalman filter (KF) ##### +# type of ensemble transformation +type_trans:int = 0 +# Ways of doing square-root of thetransform matrix +# (0) symmetric square root, (1) Cholesky decomposition +type_sqrt:int = 0 +# (1) to perform incremental updating (only in SEIK/LSEIK!) +incremental:int = 0 +# Definition of factor in covar. matrix used in SEIK +# - (0) for dim_ens^-1 (old SEIK) +# - (1) for (dim_ens-1)^-1 (real ensemble covariance matrix) +# This parameter has also to be set internally in PDAF_init. +covartype:int = 1 +# rank to be considered for inversion of HPH in analysis of EnKF +# (0) for analysis w/o eigendecomposition +# if set to >=ensemble size, it is reset to ensemble size - 1 +rank_analysis_enkf:int = 0 + + +#### localisation options #### +# Type of localization function (0: constant, 1: exponential decay, 2: 5th order polynomial) +loc_weight:int = 3 +# localization cut-off radius in grid points +cradius:float = 6.0 +# Support radius for localization function +sradius:float = cradius diff --git a/pyPDAF/source/example/offline/config_obsA.py b/pyPDAF/source/example/offline/config_obsA.py new file mode 100644 index 0000000000000000000000000000000000000000..e4e2fc6dd835f552e356024bdf56e8a279daa639 --- /dev/null +++ b/pyPDAF/source/example/offline/config_obsA.py @@ -0,0 +1,61 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This is a template file for PDAF configurations. + +The module can be modified to be adjusted to read configparser/YAML/JSON etc. to initialise +options in PDAF and the DA system. +""" +import os + + +# name of the observation +obs_name = 'A' +# path to the observation files +# here a relative path is given +obs_path:str = os.path.join('inputs_offline', 'obs.txt') +# time steps between observations / assimilation frequency +dtobs:int = 2 +# Observation error standard deviation +rms_obs:float = 0.5 +# Switch for assimilating observation type A +assim:bool = True +# Type of distance computation to use for localization +# It is mandatory for OMI even if we don't use localisation +# 0=Cartesian 1=Cartesian periodic +# details of this property can be seen at +# https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsdisttype +# currently, only PDAF V2.1 is supported +disttype:int = 0 +# Number of coordinates use for distance computation +# Here, it is a 2-dimensional domain +# https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsncoord +ncoord:int = 2 +# nrows depends on the necessity of interpolating +# observations onto model grid +# if nrows = 1, observations are on the model grid points +# when interpolation is required, +# this is the number of grid points required for interpolation. +# For example, nrows = 4 for bi-linear interpolation in 2D, +# and nrows = 8 for 3D linear interpolation. +# https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsid_obs_p +# More information about interpolation is available at +# https://pdaf.awi.de/trac/wiki/OMI_observation_operators#PDAFomi_get_interp_coeff_lin +nrows:int = 1 +# missing value in the observation +missing_value:float = -999. diff --git a/pyPDAF/source/example/offline/config_obsB.py b/pyPDAF/source/example/offline/config_obsB.py new file mode 100644 index 0000000000000000000000000000000000000000..8e238eb2e7e9362046ec52b99f12622f474ef639 --- /dev/null +++ b/pyPDAF/source/example/offline/config_obsB.py @@ -0,0 +1,61 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This is a template file for PDAF configurations. + +The module can be modified to be adjusted to read configparser/YAML/JSON etc. to initialise +options in PDAF and the DA system. +""" +import os + + +# name of the observation +obs_name = 'B' +# path to the observation files +# here a relative path is given +obs_path:str = os.path.join('inputs_offline', 'obsB.txt') +# time steps between observations / assimilation frequency +dtobs:int = 2 +# Observation error standard deviation +rms_obs:float = 0.5 +# Switch for assimilating observation type A +assim:bool = False +# Type of distance computation to use for localization +# It is mandatory for OMI even if we don't use localisation +# 0=Cartesian 1=Cartesian periodic +# details of this property can be seen at +# https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsdisttype +# currently, only PDAF V2.1 is supported +disttype:int = 0 +# Number of coordinates use for distance computation +# Here, it is a 2-dimensional domain +# https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsncoord +ncoord:int = 2 +# nrows depends on the necessity of interpolating +# observations onto model grid +# if nrows = 1, observations are on the model grid points +# when interpolation is required, +# this is the number of grid points required for interpolation. +# For example, nrows = 4 for bi-linear interpolation in 2D, +# and 8 for 3D linear interpolation. +# https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsid_obs_p +# More information about interpolation is available at +# https://pdaf.awi.de/trac/wiki/OMI_observation_operators#PDAFomi_get_interp_coeff_lin +nrows:int = 1 +# missing value in the observation +missing_value:float = -999. diff --git a/pyPDAF/source/example/offline/filter_options.py b/pyPDAF/source/example/offline/filter_options.py new file mode 100644 index 0000000000000000000000000000000000000000..b67dec71df20b59783c37bfa093259927858e462 --- /dev/null +++ b/pyPDAF/source/example/offline/filter_options.py @@ -0,0 +1,72 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import config + + +class FilterOptions: + """Here, we provide all filter options + + Attributes + ---------- + filtertype : int + the type of filter used + 1=SEIK, 2=EnKF, 3=LSEIK, 4=ETKF, 5=LETKF, 6=ESTKF, 7=LESTKF + 8=LEnKF, 9=NETF, 10=LNETF, 11=LKNETF, 12=PF, 100=GENOBS, + 200=3DVar, 0=SEEK + For a simplified documentation, see:https://pdaf.awi.de/trac/wiki/AvailableOptionsforInitPDAF + Different DA scheme requires different user-supplied functions + More information can be found in the PDAF documentation + subtype : int + Variants of each DA scheme check https://pdaf.awi.de/trac/wiki/AvailableOptionsforInitPDAF + type_forget : int + type of forgetting factor + - (0) fixed + - (1) global adaptive + - (2) local adaptive for LSEIK/LETKF/LESTKF + forget : float + forgetting factor + type_trans : int + type of ensemble transformation + type_sqrt : int + type of transform matrix square-root + incremental : int + (1) to perform incremental updating (only in SEIK/LSEIK!) + covartype : int + definition of factor in covar. matrix + rank_analysis_enkf : int + rank to be considered for inversion of HPH in analysis of EnKF + """ + + def __init__(self) -> None: + # Select filter algorithm + self.filtertype:int = config.filtertype + # Subtype of filter algorithm + self.subtype:int = config.subtype + + self.type_forget:int = config.type_forget + # forgeting factor + self.forget:float = config.forget + + # Set other parameters to default values + self.type_trans:int = config.type_trans + self.type_sqrt:int = config.type_sqrt + self.incremental:int = config.incremental + self.covartype:int = config.covartype + + self.rank_analysis_enkf:int = config.rank_analysis_enkf diff --git a/pyPDAF/source/example/offline/localisation.py b/pyPDAF/source/example/offline/localisation.py new file mode 100644 index 0000000000000000000000000000000000000000..3a82d3ba0d6b66fb5c1bbba579bd292e1c4e79cf --- /dev/null +++ b/pyPDAF/source/example/offline/localisation.py @@ -0,0 +1,147 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import log + +import numpy as np +import pyPDAF + +import config +import parallelisation +import state_vector + + +class Localisation: + + """class for localization information and user-supplied functions + + Attributes + ---------- + loc_weight : int + - (0) constant weight of 1 + - (1) exponentially decreasing with sradius + - (2) use 5th-order polynomial + - (3) regulated localization of R with mean error variance + - (4) regulated localization of R with single-point error variance + cradius : float + range for local observation domain + sradius : float + support range for 5th order polynomial + or radius for 1/e for exponential weighting + local_filter : bool + a boolean variable determining whether a local filter is used + by default, it is false and will be later determined by PDAF function + in init_pdaf + sv : state_vector.state_vector + a reference to the state vector object + + Methods + ------- + init_n_domains(self, n_domains:int) + initialise the number of local domains + """ + + def __init__(self, sv:state_vector.StateVector) -> None: + """class constructor + + Parameters + ---------- + sv : 'state_vector.state_vector' + state vector object + """ + self.loc_weight:int = config.loc_weight + self.cradius:float = config.cradius + self.sradius:float = config.sradius + # a boolean variable determining whether a local filter is used + # by default, it is false and will be later determined by PDAF function + # in init_pdaf + self.local_filter:bool = False + # a reference to the state vector object + self.sv:state_vector.StateVector = sv + + def init_n_domains_pdaf(self, _step:int, _ndomains:int) -> int: + """initialize the number of local domains + + Parameters + ----------` + step : int + current time step + ndomains: int + number of local domains on current processor + + Returns + ------- + n_domains_p : int + PE-local number of analysis domains + """ + output_str = f'ndomains: ndomains {self.sv.dim_state_p}' + log.logger.info(output_str) + return self.sv.dim_state_p + + def set_lim_coords(self, nx_p:int, ny_p:int, pe:parallelisation.Parallelisation) -> None: + """set local domain + + Parameters + ---------- + nx_p : int + size of PE-local state vector in x-direction + ny_p : int + size of PE-local state vector in y-direction + pe : 'parallelisation.parallelisation' + parallelization object + """ + # Get offset of local domain in global domain in x-direction + # The the following link for more information + # https://pdaf.awi.de/trac/wiki/PDAFomi_additional_functionality#PDAFomi_set_domain_limits + # note that this is Fortran-based documentation where array index + # starts from 1 + off_nx = nx_p*pe.mype_filter + + lim_coords = np.zeros((2, 2), order='F') + lim_coords[0, 0] = float(off_nx + 1) + lim_coords[0, 1] = float(off_nx + nx_p) + lim_coords[1, 0] = ny_p + lim_coords[1, 1] = 1 + + pyPDAF.PDAFomi.set_domain_limits(lim_coords) + + def init_dim_l_pdaf(self, _step:int, domain_p:int, dim_l:int) -> int: + """initialise the local dimension of PDAF. + + The function returns + the dimension of local state vector + + Parameters + ---------- + step : int + current time step + domain_p : int + index of current local analysis domain + dim_l : int + dimension of local state vector + + Returns + ------- + dim_l : int + dimension of local state vector + """ + # initialize local state dimension + dim_l = 1 + id_lstate_in_pstate:np.ndarray = domain_p*np.ones((dim_l), dtype=np.intc) + pyPDAF.PDAFlocal.set_indices(dim_l, id_lstate_in_pstate) + return dim_l diff --git a/pyPDAF/source/example/offline/log.py b/pyPDAF/source/example/offline/log.py new file mode 100644 index 0000000000000000000000000000000000000000..26e871aae25ac0aee7d7008adf90ad8473773dd7 --- /dev/null +++ b/pyPDAF/source/example/offline/log.py @@ -0,0 +1,27 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import logging +import sys + +logger = logging.getLogger() +logger.setLevel(logging.DEBUG) +ch = logging.StreamHandler() +formatter = logging.Formatter('%(levelname)s: %(message)s') +ch.setFormatter(formatter) +logger.addHandler(ch) \ No newline at end of file diff --git a/pyPDAF/source/example/offline/main.py b/pyPDAF/source/example/offline/main.py new file mode 100644 index 0000000000000000000000000000000000000000..c73192ec39fb853589671149a2dc18ad3f11da89 --- /dev/null +++ b/pyPDAF/source/example/offline/main.py @@ -0,0 +1,51 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +""" +import log + +import config +import model +from parallelisation import Parallelisation +from pdaf_system import PDAFsystem + +def main(): + pe = Parallelisation(dim_ens=config.dim_ens) + + # Initial Screen output + if pe.mype_ens == 0: + log.logger.info('+++++ PDAF offline mode +++++') + log.logger.info('2D model with parallelization') + + # Initialise model grid for localisation/observation operator + model_grid = model.ModelGrid(pe=pe) + model_grid.print_info(pe) + + # Initialise PDAF system + das = PDAFsystem(pe, model_grid) + + das.init_pdaf(screen=config.screen) + + das.assimilate() + + das.finalise() + + pe.finalize_parallel() + +if __name__ == '__main__': + main() diff --git a/pyPDAF/source/example/offline/model.py b/pyPDAF/source/example/offline/model.py new file mode 100644 index 0000000000000000000000000000000000000000..6a880399e81b686d5633a32fec5b8b806c410d5d --- /dev/null +++ b/pyPDAF/source/example/offline/model.py @@ -0,0 +1,93 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import log + +import config +import parallelisation + +class ModelGrid: + """Model information in PDAF + + Attributes + ---------- + field_p : ndarray + PE-local model field + nx : int + number of grid points in x-direction + nx_p : int + number of grid points in x-direction on local PE + ny : int + number of grid points in y-direction + ny_p : int + number of grid points in y-direction on local PE + total_steps : int + total number of time steps + """ + + def __init__(self, pe:parallelisation.Parallelisation) -> None: + """constructor + + Parameters + ---------- + pe : `parallelization.parallelization` + parallelization object + """ + # model size + self.nx:int = config.nx + self.ny:int = config.ny + # model domain for each CPU (model domain decomposition) + self.nx_p:int + self.ny_p:int + self.nx_p, self.ny_p = self.get_local_domain(pe) + + def get_local_domain(self, pe:parallelisation.Parallelisation + ) -> tuple[int, int]: + """Compute local-PE domain size/domain decomposition + + Parameters + ---------- + pe : `parallelization.parallelization` + parallelization object + """ + nx_p:int = self.nx + ny_p:int = self.ny + + assert self.nx % pe.npes_model == 0, f'...ERROR: ' \ + f'Invalid number of processes: {pe.npes_model}...' + # we parallelise the domain column by column + nx_p = self.nx//pe.npes_model + + return nx_p, ny_p + + def print_info(self, pe:parallelisation.Parallelisation) -> None: + """print model info + + Parameters + ---------- + pe : `parallelization.parallelization` + parallelization object + """ + if pe.mype_model == 0: + log.logger.info('Initialise model grid') + output_str = f'Grid size: {self.nx} x {self.ny}' + log.logger.info(output_str) + output_str = f'-- Domain decomposition over {pe.npes_model} PEs' + log.logger.info(output_str) + output_str = f'-- local domain sizes: {self.nx_p} x {self.ny_p}' + log.logger.info(output_str) \ No newline at end of file diff --git a/pyPDAF/source/example/offline/obs_a.py b/pyPDAF/source/example/offline/obs_a.py new file mode 100644 index 0000000000000000000000000000000000000000..c44e3b5c99283a3bae07c29c07011b4cb0f1440a --- /dev/null +++ b/pyPDAF/source/example/offline/obs_a.py @@ -0,0 +1,305 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import log + +import numpy as np +import pyPDAF.PDAFomi + +import config_obsA as config +import localisation +import model +import parallelisation + +class ObsA: + + """observation functions for type-A observation + + Attributes + ---------- + i_obs : int + index of the observation type + obs_name : str + name of the current observation type + filename : str + observation filename to be read + dim_obs_p : int + dimension size of the PE-local observation vector + disttype : int + type of distance computation to use for localization + doassim : int + whether to assimilate this observation type + ncoord : int + number of coordinate dimension + nrows : int + number of rows in ocoord_p + dtobs : int + time interval between observations + missing_value : float + missing value in observations (filled by -9999.0 for example) + model_t : model.model + model object + pe : parallelisation.parallelisation + parallelization object + local : localisation.localisation + localisation object + """ + + def __init__(self, i_obs:int, + pe:parallelisation.Parallelisation, + model_t:model.ModelGrid, local:localisation.Localisation) -> None: + # i_obs-th observations in the system starting from 1 + self.i_obs:int = i_obs + self.obs_name:str = config.obs_name + assert self.i_obs >= 1, 'observation count must start from 1' + # observation filename + self.filename:str = config.obs_path + # whether this observation is assimilated + self.doassim:int = 0 + # Type of distance computation to use for localization + # It is mandatory for OMI even if we don't use localisation + # 0=Cartesian 1=Cartesian periodic + # details of this property can be seen at + # https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsdisttype + # currently, only PDAF V2.1 is supported + self.disttype:int = config.disttype + # Number of coordinates use for distance computation + # Here, it is a 2-dimensional domain + # https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsncoord + self.ncoord:int = config.ncoord + # nrows depends on the necessity of interpolating + # observations onto model grid + # if nrows = 1, observations are on the model grid points + # when interpolation is required, + # this is the number of grid points required for interpolation. + # For example, nrows = 4 for bi-linear interpolation in 2D, + # and 8 for 3D linear interpolation. + # https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsid_obs_p + # More information about interpolation is available at + # https://pdaf.awi.de/trac/wiki/OMI_observation_operators#PDAFomi_get_interp_coeff_lin + self.nrows:int = config.nrows + self.dtobs = config.dtobs + # specify the missing/filled value of the observations + self.missing_value:float = config.missing_value + self.model:model.ModelGrid = model_t + self.pe:parallelisation.Parallelisation = pe + self.local:localisation.Localisation = local + + + def init_dim(self, step:int, dim_obs:int) -> int: + """In PDAFomi, init_dim takes the responsibility to + set the obs_f object, gather information on the observations + including the observation values, observation error, index of + the state vector of the observation, the model domain and + observation coordinate for interpolation, and the distance metric + for localisation. + + + Parameters + ---------- + step : int + current time step + dim_obs : int + dimension of observation vector + + Returns + ------- + int + dimension of observation vector + """ + if self.pe.mype_filter == 0: + output_str = f'Assimilate observations: {self.obs_name}' + log.logger.info(output_str) + + # switch for assimilation of the observation + pyPDAF.PDAFomi.set_doassim(self.i_obs, self.doassim) + # Type of distance computation to use for localization + # It is mandatory for OMI even if we don't use localisation + pyPDAF.PDAFomi.set_disttype(self.i_obs, self.disttype) + # Number of coordinates used for distance computation + pyPDAF.PDAFomi.set_ncoord(self.i_obs, self.ncoord) + + # read observations + filename = self.filename.format(i=step) + obs_field:np.ndarray = np.loadtxt(filename) + # when domain decomposition is used, we only need observations + # within the local model domain + pe_start:int = self.model.nx_p*self.pe.mype_filter + pe_end:int = pe_start + self.model.nx_p + obs_field_p:np.ndarray = obs_field[:, pe_start:pe_end].ravel() + # get total number of valid observations + # a mask for invalid observations + condition:np.ndarray = np.logical_not(np.isclose(obs_field_p, self.missing_value)) + dim_obs_p:int = np.sum(condition) + # obtain the observation vector + obs_p:np.ndarray = obs_field_p[condition] + assert len(obs_p) == dim_obs_p, f'dimension of the observation vector ({len(obs_p)})'\ + f'should be the same as the dim_obs_p ({dim_obs_p})' + + # inverse of observation variance + # here we specify/hard-code the standard deviation of observation is 0.5 + ivar_obs_p:np.ndarray = (1./config.rms_obs/config.rms_obs)*np.ones_like(obs_p) + + # coordinate of each observations + ocoord_p:np.ndarray = np.zeros((self.ncoord, len(obs_p)), order='F') + ocoord_p[0] = np.tile(np.arange(self.model.nx_p) + pe_start, self.model.ny_p)[condition] + ocoord_p[1] = np.repeat(np.arange(self.model.ny_p), self.model.nx_p)[condition] + ocoord_p = ocoord_p + 1. + + + id_obs_p:np.ndarray = np.zeros((self.nrows, len(obs_p)), dtype=np.intc, order='F') + if self.nrows == 1: + # The relationship between observation and state vector + # id_obs_p gives the indices of observed field in state vector + # the index starts from 1 + # The index is based on the full state vector instead of the index in the local domain + # The following code is used because in our example, observations are masked and + # have the same shape as the model grid + state_vector_index_p:np.ndarray = np.arange(1, + self.model.nx_p*self.model.ny_p + 1, + dtype=np.intc) + id_obs_p[0] = state_vector_index_p[condition] + else: + # If interpolation is required for a 2D domain + # id_obs_p has a dimension of (4, dim_obs_p) + # id_obs_p[0] is the index of the grid point in the state vector + # at lower left of the observation + # for more details of the interpolation see: + # https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsid_obs_p + # and + # https://pdaf.awi.de/trac/wiki/OMI_observation_operators#PDAFomi_get_interp_coeff_lin + # In this case, we also need to specify the coefficients for linear interpolation + # using PDAF.omi_get_interp_coeff_lin() function and set icoeff_p to PDAF + icoeff_p:np.ndarray = np.zeros((self.nrows, len(obs_p)), order='F') + for i in range(dim_obs_p): + # here gcoords are set to 0 in this example + # in real applications, it must be the actual coordinates + gcoords:np.ndarray = np.zeros((self.nrows, self.ncoord), order='F') + icoeff_p[:, i] = pyPDAF.PDAFomi.get_interp_coeff_lin(self.nrows, self.ncoord, + gcoords, + ocoord_p[:, i], + icoeff_p[:, i]) + pyPDAF.PDAFomi.set_icoeff_p(self.i_obs, self.nrows, dim_obs_p, icoeff_p) + pyPDAF.PDAFomi.set_id_obs_p(self.i_obs, self.nrows, dim_obs_p, id_obs_p) + + # Type of observation error: (0) Gauss, (1) Laplace + # This is optional + # Without explicit setting, this is 0 + pyPDAF.PDAFomi.set_obs_err_type(self.i_obs, 0) + + # Whether to use (1) global full obs. + # (0) obs. restricted to those relevant for a process domain + # Without explicit setting, this is 1 (using all obs.) + pyPDAF.PDAFomi.set_use_global_obs(self.i_obs, 1) + + # when localisation is used we need to + if self.local.local_filter: + # Size of domain for periodicity for disttype=1 + # (<0 for no periodicity) + domainsize:np.ndarray = np.array([self.model.nx, self.model.ny], dtype=float) + pyPDAF.PDAFomi.set_domainsize(self.i_obs, self.ncoord, domainsize) + + # PDAF need to gather observation information + dim_obs = pyPDAF.PDAFomi.gather_obs(self.i_obs, dim_obs_p, + obs_p, + ivar_obs_p, + ocoord_p, self.ncoord, + self.local.cradius) + + # set covariance localisation for stochastic EnKF/EAKF/EnSRF + if pyPDAF.PDAF.get_local_type() > 1: + dim_p = self.model.nx*self.model.ny + coords_p = np.zeros((2, dim_p), order='F') + offset = self.pe.mype_filter*self.model.nx_p + coords_p[0] = np.tile(np.arange(self.model.nx_p) + \ + offset, self.model.ny_p) + coords_p[1] = np.repeat(np.arange(self.model.ny_p), + self.model.nx_p) + pyPDAF.PDAFomi.set_localize_covar_iso(self.i_obs, dim_p, + self.ncoord, coords_p, + self.local.loc_weight, + self.local.cradius, + self.local.sradius) + + return dim_obs + + def init_dim_obs_l(self, domain_p:int, _step:int, _dim_obs:int, dim_obs_l:int) -> int: + """intialise local observation vector for domain localisation + + Parameters + ---------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs : int + dimension of observation vector + dim_obs_l : int + dimension of local observation vector + + Returns + ------- + dim_obs_l : int + dimension of local observations + """ + # initialize coordinates of local domain + # we use grid point indices as coordinates, + # but could e.g. use meters + coords_l:np.ndarray = np.zeros(self.ncoord) + # we comment out the smart way to calculate the index + # offset = self.pe.mype_filter*self.model.nx_p*self.model.ny_p + # coords_l[0] = domain_p + offset - 1 + # coords_l[0] = coords_l[0]//self.model.ny_p + # coords_l[1] = domain_p + offset - 1 + # coords_l[1] = coords_l[1] - coords_l[0]*self.model.ny_p + + # here is a brutal force way where we simply list all coordinates on each local processor + # and index them based on domain_p + offset:int = self.pe.mype_filter*self.model.nx_p + coords_l[0] = np.tile(np.arange(self.model.nx_p) + offset, self.model.ny_p)[domain_p - 1] + coords_l[1] = np.repeat(np.arange(self.model.ny_p), self.model.nx_p)[domain_p - 1] + coords_l = coords_l + 1. + + return pyPDAF.PDAFomi.init_dim_obs_l_iso(self.i_obs, coords_l, + self.local.loc_weight, + self.local.cradius, + self.local.sradius, dim_obs_l) + + + def obs_op(self, _step:int, state_p:np.ndarray, ostate:np.ndarray) -> np.ndarray: + """convert state vector by observation operator + + Parameters + ---------- + step : int + current time step + state_p : ndarray + PE-local state vector + ostate : ndarray + state vector transformed by identity matrix + + Returns + ------- + ostate : ndarray + state vector transformed by identity matrix + """ + if self.nrows == 1: + return pyPDAF.PDAFomi.obs_op_gridpoint(self.i_obs, state_p, ostate) + + # if interpolation is required + return pyPDAF.PDAFomi.obs_op_interp_lin(self.i_obs, self.nrows, state_p, ostate) diff --git a/pyPDAF/source/example/offline/obs_b.py b/pyPDAF/source/example/offline/obs_b.py new file mode 100644 index 0000000000000000000000000000000000000000..0b5df00443dbda1b8ec8617bc4b77c4051c04611 --- /dev/null +++ b/pyPDAF/source/example/offline/obs_b.py @@ -0,0 +1,287 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import log + +import numpy as np +import pyPDAF.PDAFomi + +import config_obsB as config +import localisation +import model +import parallelisation + +class ObsB: + + """observation functions for type-B observation + Attributes + ---------- + i_obs : int + index of the observation type + obs_name : str + name of the current observation type + filename : str + observation filename to be read + dim_obs_p : int + dimension size of the PE-local observation vector + disttype : int + type of distance computation to use for localization + doassim : int + whether to assimilate this observation type + ncoord : int + number of coordinate dimension + nrows : int + number of rows in ocoord_p + dtobs : int + time interval between observations + missing_value : float + missing value in observations (filled by -9999.0 for example) + model_t : model.model + model object + pe : parallelisation.parallelisation + parallelization object + local : localisation.localisation + localisation object + """ + + def __init__(self, i_obs:int, + pe:parallelisation.Parallelisation, + model_t:model.ModelGrid, local:localisation.Localisation) -> None: + # i_obs-th observations in the system starting from 1 + self.i_obs:int = i_obs + self.obs_name:str = config.obs_name + assert self.i_obs >= 1, 'observation count must start from 1' + # observation filename + self.filename:str = config.obs_path + # whether this observation is assimilated + self.doassim:int = 0 + # Type of distance computation to use for localization + # It is mandatory for OMI even if we don't use localisation + # 0=Cartesian 1=Cartesian periodic + # details of this property can be seen at + # https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsdisttype + # currently, only PDAF V2.1 is supported + self.disttype:int = config.disttype + # Number of coordinates use for distance computation + # Here, it is a 2-dimensional domain + # https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsncoord + self.ncoord:int = config.ncoord + # nrows depends on the necessity of interpolating + # observations onto model grid + # if nrows = 1, observations are on the model grid points + # when interpolation is required, + # this is the number of grid points required for interpolation. + # For example, nrows = 4 for bi-linear interpolation in 2D, + # and 8 for 3D linear interpolation. + # https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsid_obs_p + # More information about interpolation is available at + # https://pdaf.awi.de/trac/wiki/OMI_observation_operators#PDAFomi_get_interp_coeff_lin + self.nrows:int = config.nrows + self.dtobs = config.dtobs + # specify the missing/filled value of the observations + self.missing_value:float = config.missing_value + self.model:model.ModelGrid = model_t + self.pe:parallelisation.Parallelisation = pe + self.local:localisation.Localisation = local + + + def init_dim(self, step:int, dim_obs:int) -> int: + """In PDAFomi, init_dim takes the responsibility to + set the obs_f object, gather information on the observations + including the observation values, observation error, index of + the state vector of the observation, the model domain and + observation coordinate for interpolation, and the distance metric + for localisation. + + + Parameters + ---------- + step : int + current time step + dim_obs : int + dimension of observation vector + + Returns + ------- + int + dimension of observation vector + """ + if self.pe.mype_filter == 0: + output_str = f'Assimilate observations: {self.obs_name}' + log.logger.info(output_str) + + # switch for assimilation of the observation + pyPDAF.PDAFomi.set_doassim(self.i_obs, self.doassim) + # Type of distance computation to use for localization + # It is mandatory for OMI even if we don't use localisation + pyPDAF.PDAFomi.set_disttype(self.i_obs, self.disttype) + # Number of coordinates used for distance computation + pyPDAF.PDAFomi.set_ncoord(self.i_obs, self.ncoord) + + # read observations + filename = self.filename.format(i=step) + obs_field:np.ndarray = np.loadtxt(filename) + # when domain decomposition is used, we only need observations + # within the local model domain + pe_start:int = self.model.nx_p*self.pe.mype_filter + pe_end:int = pe_start + self.model.nx_p + obs_field_p:np.ndarray = obs_field[:, pe_start:pe_end].ravel() + # get total number of valid observations + # a mask for invalid observations + condition:np.ndarray = np.logical_not(np.isclose(obs_field_p, self.missing_value)) + dim_obs_p:int = np.sum(condition) + # obtain the observation vector + obs_p:np.ndarray = obs_field_p[condition] + assert len(obs_p) == dim_obs_p, f'dimension of the observation vector ({len(obs_p)})'\ + f'should be the same as the dim_obs_p ({dim_obs_p})' + + # inverse of observation variance + # here we specify/hard-code the standard deviation of observation is 0.5 + ivar_obs_p:np.ndarray = (1./config.rms_obs/config.rms_obs)*np.ones_like(obs_p) + + # coordinate of each observations + ocoord_p:np.ndarray = np.zeros((self.ncoord, len(obs_p)), order='F') + ocoord_p[0] = np.tile(np.arange(self.model.nx_p) + pe_start, self.model.ny_p)[condition] + ocoord_p[1] = np.repeat(np.arange(self.model.ny_p), self.model.nx_p)[condition] + ocoord_p = ocoord_p + 1. + + + id_obs_p:np.ndarray = np.zeros((self.nrows, len(obs_p)), dtype=np.intc, order='F') + if self.nrows == 1: + # The relationship between observation and state vector + # id_obs_p gives the indices of observed field in state vector + # the index starts from 1 + # The index is based on the full state vector instead of the index in the local domain + # The following code is used because in our example, observations are masked and + # have the same shape as the model grid + state_vector_index_p:np.ndarray = np.arange(1, + self.model.nx_p*self.model.ny_p + 1, + dtype=np.intc) + id_obs_p[0] = state_vector_index_p[condition] + else: + # If interpolation is required for a 2D domain + # id_obs_p has a dimension of (4, dim_obs_p) + # id_obs_p[0] is the index of the grid point in the state vector + # at lower left of the observation + # for more details of the interpolation see: + # https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsid_obs_p + # and + # https://pdaf.awi.de/trac/wiki/OMI_observation_operators#PDAFomi_get_interp_coeff_lin + # In this case, we also need to specify the coefficients for linear interpolation + # using PDAF.omi_get_interp_coeff_lin() function and set icoeff_p to PDAF + icoeff_p:np.ndarray = np.zeros((self.nrows, len(obs_p)), order='F') + for i in range(dim_obs_p): + # here gcoords are set to 0 in this example + # in real applications, it must be the actual coordinates + gcoords:np.ndarray = np.zeros((self.nrows, self.ncoord), order='F') + icoeff_p[:, i] = pyPDAF.PDAFomi.get_interp_coeff_lin(self.nrows, self.ncoord, + gcoords, ocoord_p[:, i], + icoeff_p[:, i]) + pyPDAF.PDAFomi.set_icoeff_p(self.i_obs, self.nrows, dim_obs_p, icoeff_p) + pyPDAF.PDAFomi.set_id_obs_p(self.i_obs, self.nrows, dim_obs_p, id_obs_p) + + # Type of observation error: (0) Gauss, (1) Laplace + # This is optional + # Without explicit setting, this is 0 + pyPDAF.PDAFomi.set_obs_err_type(self.i_obs, 0) + + # Whether to use (1) global full obs. + # (0) obs. restricted to those relevant for a process domain + # Without explicit setting, this is 1 (using all obs.) + pyPDAF.PDAFomi.set_use_global_obs(self.i_obs, 1) + + # when localisation is used + if self.local.local_filter: + # Size of domain for periodicity for disttype=1 + # (<0 for no periodicity) + domainsize:np.ndarray = np.array([self.model.nx, self.model.ny], dtype=float) + pyPDAF.PDAFomi.set_domainsize(self.i_obs, self.ncoord, domainsize) + + # PDAF need to gather observation information + dim_obs = pyPDAF.PDAFomi.gather_obs(self.i_obs, dim_obs_p, + obs_p, + ivar_obs_p, + ocoord_p, self.ncoord, + self.local.cradius) + return dim_obs + + def init_dim_obs_l(self, domain_p:int, _step:int, _dim_obs:int, dim_obs_l:int) -> int: + """intialise local observation vector for domain localisation + + Parameters + ---------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs : int + dimension of observation vector + dim_obs_l : int + dimension of local observation vector + + Returns + ------- + dim_obs_l : int + dimension of local observations + """ + # initialize coordinates of local domain + # we use grid point indices as coordinates, + # but could e.g. use meters + coords_l:np.ndarray = np.zeros(self.ncoord) + # we comment out the smart way to calculate the index + # offset = self.pe.mype_filter*self.model.nx_p*self.model.ny_p + # coords_l[0] = domain_p + offset - 1 + # coords_l[0] = coords_l[0]//self.model.ny_p + # coords_l[1] = domain_p + offset - 1 + # coords_l[1] = coords_l[1] - coords_l[0]*self.model.ny_p + + # here is a brutal force way where we simply list all coordinates on each local processor + # and index them based on domain_p + offset:int = self.pe.mype_filter*self.model.nx_p + coords_l[0] = np.tile(np.arange(self.model.nx_p) + offset, self.model.ny_p)[domain_p - 1] + coords_l[1] = np.repeat(np.arange(self.model.ny_p), self.model.nx_p)[domain_p - 1] + coords_l = coords_l + 1. + + return pyPDAF.PDAFomi.init_dim_obs_l_iso(self.i_obs, coords_l, + self.local.loc_weight, + self.local.cradius, + self.local.sradius, dim_obs_l) + + + def obs_op(self, _step:int, state_p:np.ndarray, ostate:np.ndarray) -> np.ndarray: + """convert state vector by observation operator + + Parameters + ---------- + step : int + current time step + state_p : ndarray + PE-local state vector + ostate : ndarray + state vector transformed by identity matrix + + Returns + ------- + ostate : ndarray + state vector transformed by identity matrix + """ + if self.nrows == 1: + return pyPDAF.PDAFomi.obs_op_gridpoint(self.i_obs, state_p, ostate) + + # if interpolation is required + return pyPDAF.PDAFomi.obs_op_interp_lin(self.i_obs, self.nrows, state_p, ostate) diff --git a/pyPDAF/source/example/offline/obs_factory.py b/pyPDAF/source/example/offline/obs_factory.py new file mode 100644 index 0000000000000000000000000000000000000000..d3367fc72e8fb6a959d995103516fc5550d507de --- /dev/null +++ b/pyPDAF/source/example/offline/obs_factory.py @@ -0,0 +1,150 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import log + +import numpy as np + +import config_obsA +import config_obsB +import localisation +import model +import obs_a +import obs_b +import parallelisation + +class ObsFactory: + """This class implements all user-supplied functions + used by PDAFomi. These functions are called at every time steps + + Attributes + ---------- + pe : `parallelisation.parallelisation` + parallelization object + model : `model.model` + model object + local : `localisation.localisation` + localisation object + obs_list : list + list of observation types + nobs : int + total number of observation types + """ + def __init__(self, pe:parallelisation.Parallelisation, + model_t:model.ModelGrid, local:localisation.Localisation) -> None: + # Initialise observations + self.pe: parallelisation.Parallelisation = pe + self.model:model.ModelGrid = model_t + self.local:localisation.Localisation = local + self.obs_list:list = [] + self.nobs:int = 0 + if config_obsA.assim: + self.nobs += 1 + self.obs_list.append(obs_a.ObsA(self.nobs, self.pe, self.model, self.local) + ) + if config_obsB.assim: + self.nobs += 1 + self.obs_list.append(obs_b.ObsB(self.nobs, self.pe, self.model, self.local) + ) + output_str = f'total number of observation types: {self.nobs}' + log.logger.info (output_str) + + def init_dim_obs_pdafomi(self, step:int, dim_obs:int) -> int: + """initialise observation dimensions + + Parameters + ---------- + step : int + current time step + dim_obs : int + dimension of observation vector + + Returns + ------- + dim_obs : int + dimension of observation vector + """ + # it is possibly useful to add some checks on obs.doassim here + # For example, set obs.doassim = 0 if one type of observation + # is not used for this particular step. + for obs in self.obs_list: + if step % obs.dtobs == 0: + obs.doassim = 1 + # calculate the dimension of full observation vector + dim_obs = 0 + for obs in self.obs_list: + if obs.doassim == 1: + dim_obs_o:int = obs.init_dim(step, dim_obs) + dim_obs = dim_obs + dim_obs_o + + return dim_obs + + def obs_op_pdafomi(self, step:int, _dim_p:int, _dim_obs_p:int, + state_p:np.ndarray, ostate:np.ndarray) -> np.ndarray: + """turn state vector to observation space + + Parameters + ---------- + step : int + current time step + dim_p: int + dimension of state vector on local processor + dim_obs_p: int + dimension of observation vector on local processor + state_p : ndarray + local PE state vector + ostate : ndarray + state vector in obs space + + Returns + ------- + ostate : ndarray + state vector in obs space + """ + + for obs in self.obs_list: + if obs.doassim == 1: + ostate = obs.obs_op(step, state_p, ostate) + return ostate + + def init_dim_obs_l_pdafomi(self, domain_p:int, step:int, dim_obs:int, dim_obs_l:int) -> int: + """initialise number of observations in each local domain + + Parameters + ---------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs : int + dimension of observation vector + dim_obs_l : int + dimension of local observation vector + + Returns + ------- + dim_obs_l : int + dimension of local observation vector + """ + dim_obs_l = 0 + for obs in self.obs_list: + if obs.doassim == 1: + dim_obs_l_o:int = obs.init_dim_obs_l(domain_p, step, dim_obs, dim_obs_l) + dim_obs_l = dim_obs_l + dim_obs_l_o + + return dim_obs_l diff --git a/pyPDAF/source/example/offline/parallelisation.py b/pyPDAF/source/example/offline/parallelisation.py new file mode 100644 index 0000000000000000000000000000000000000000..185421a2d51836021f35460352193aade1c917a9 --- /dev/null +++ b/pyPDAF/source/example/offline/parallelisation.py @@ -0,0 +1,300 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import log + +from mpi4py import MPI +import numpy as np + +import pyPDAF + + +class Parallelisation: + + """Summary + + Attributes + ---------- + n_modeltasks : int + number of model tasks run in parallel + dim_ens : int + total ensemble size + + comm_ens : `MPI.Comm` + ensemble communicator + npes_ens : int + number of global PEs + mype_ens : int + rank of ens communicator + local_npes_model : int + number of model PEs used by each model task + task_id : int + model task id of the current processor + comm_model : `MPI.Comm` + model communicator + npes_model : int + number of model PEs + mype_model : int + rank of model communicator + dim_ens_l : int + number of ensemble members per model task + This is the same as dim_ens//n_modeltasks + for each model task in parallel + all_dim_ens_l : np.ndarray + number of ensemble members across all PEs. + filterpe : bool + whether the PE is used for filter + comm_filter : `MPI.Comm` + filter communicator + npes_filter : int + number of filter PEs + mype_filter : int + rank of filter communicator + comm_couple : `MPI.Comm` + model and filter coupling communicator + """ + + def __init__(self, dim_ens:int) -> None: + """Init the parallization required by PDAF + + Parameters + ---------- + dim_ens : TYPE + Description + n_modeltasks : int + Number of model tasks/ ensemble size + This parameter should be the same + as the number of PEs + """ + + # number of model tasks run in parallel + # this is limited by the number of processors + self.n_modeltasks:int = 1 + # total number of ensemble members. This can be larger than + # number of parallel model tasks where the 'flexible' implementation + # is used + self.dim_ens:int = dim_ens + + # Initialize model communicator, its size and the process rank + # Here the same as for MPI_COMM_WORLD + self.comm_ens:MPI.Comm + self.npes_ens:int + self.mype_ens:int + self.comm_ens, self.npes_ens, self.mype_ens = self.init_parallel() + + self.is_task_consistent() + self.is_cpu_consistent() + + # Initialize communicators for ensemble evaluations + if self.mype_ens == 0: + log.logger.info('Initialize communicators for assimilation with PDAF') + + # get the number of processors used by each model task + self.local_npes_model:np.ndarray = self.get_processor_per_model() + self.task_id:int = self.get_task_id() + # get model communicator + self.comm_model:MPI.Comm + self.npes_model:int + self.mype_model:int + self.comm_model, self.npes_model, self.mype_model = self.get_model_communicator() + + # local ensemble member of each model task/processors. + # When dim_ens > n_modeltasks, some processors/model tasks + # run dim_ens_l number of members sequentially. + # When n_modeltasks = dim_ens, dim_ens_l = 1 + # Here dim_ens_l is the ensemble size for current model task + # all_dim_ens_l is the ensemble size for all task ids. + # self.dim_ens_l:int + # self.all_dim_ens_l:np.ndarray + # self.dim_ens_l, self.all_dim_ens_l = self.get_dim_ens_l() + + output_str = f'MODEL: mype(w)= {self.mype_ens}' \ + f'; model task: {self.task_id}' \ + f'; mype(m)= {self.mype_model}' \ + f'; npes(m)= {self.npes_model}' + log.logger.info(output_str) + + # Generate communicator for filter + self.filter_pe:bool + self.comm_filter:MPI.Comm + self.npes_filter:int + self.mype_filter:int + self.filter_pe, self.comm_filter = self.get_filter_communicator() + self.npes_filter, self.mype_filter = self.get_filter_communicator_size_rank() + + # Generate communicators for communication + self.comm_couple:MPI.Comm = self.get_couple_communicator() + + self.print_info() + + status = 0 + status = pyPDAF.set_parallel(self.comm_ens.py2f(), self.comm_model.py2f(), + self.comm_filter.py2f(), self.comm_couple.py2f(), + self.task_id, self.n_modeltasks, self.filter_pe, status) + + def init_parallel(self) -> tuple[MPI.Comm, int, int]: + """Initialize MPI + + Routine to initialize MPI. + + Here, we also return the communicator for the full ensemble + as well as its size and the rank of the current processor in + the communicator. + + In this simple example, the full ensemble communicator is the + MPI_COMM_WORLD. + """ + if not MPI.Is_initialized(): + MPI.Init() + + return MPI.COMM_WORLD, MPI.COMM_WORLD.Get_size(), MPI.COMM_WORLD.Get_rank() + + def get_processor_per_model(self) -> np.ndarray: + """Store # PEs per ensemble + used for info on PE 0 and for generation + of model communicators on other Pes + """ + + local_npes_model:np.ndarray = np.zeros(self.n_modeltasks, dtype=int) + + local_npes_model[:] = np.floor( + self.npes_ens/self.n_modeltasks) + + size:int = self.npes_ens \ + - self.n_modeltasks * local_npes_model[0] + local_npes_model[:size] = local_npes_model[:size] + 1 + + return local_npes_model + + def get_task_id(self) -> int: + """get model communicator + Generate communicators for model runs + (Split COMM_ENSEMBLE) + """ + pe_index:np.ndarray = np.cumsum(self.local_npes_model, dtype=int) + # task id of the current processor + task_id:int = np.arange(self.n_modeltasks)[pe_index <= + self.mype_ens + self.local_npes_model[0]][-1] + 1 + + return task_id + + def get_model_communicator(self) -> tuple[MPI.Comm, int, int]: + """get model PE rank and size + """ + comm_model = MPI.COMM_WORLD.Split(self.task_id, self.mype_ens) + return comm_model, comm_model.Get_size(), comm_model.Get_rank() + + def get_dim_ens_l(self) -> tuple[int, np.ndarray]: + """obtain number of ensemble members for each model task + + This means that each model task has to run dim_ens_l + number of ensemble members sequentially + """ + # number of ensemble for each model task + dim_ens_l:int = self.dim_ens//self.n_modeltasks + residual:int = self.dim_ens - dim_ens_l*self.n_modeltasks + # number of ensmeble members across all PEs + # e.g. self.all_dim_ens_l[0] is the ensemble size on the first PE + # and self.all_dim_ens_l[-1] is the ensemble size on the last PE + all_dim_ens_l:np.ndarray = dim_ens_l*np.ones(self.n_modeltasks, dtype=int) + all_dim_ens_l[:residual] += 1 + # number of tasks on local PE + dim_ens_l = all_dim_ens_l[self.task_id - 1] + if self.mype_ens == 0: + output_str = f'number of Ens per PE {all_dim_ens_l}' + log.logger.debug (output_str) + return dim_ens_l, all_dim_ens_l + + def get_filter_communicator(self) -> tuple[bool, MPI.Comm]: + """Generate communicator for filter + """ + # filter is only conducted in the first model task + filterpe:bool = True if self.task_id == 1 else False + my_color:int = self.task_id if filterpe else MPI.UNDEFINED + comm_filter:MPI.Comm = MPI.COMM_WORLD.Split(my_color, self.mype_ens) + return filterpe, comm_filter + + def get_filter_communicator_size_rank(self) -> tuple[int, int]: + """get filter PE rank and size which should be same as model size and rank + """ + return self.comm_model.Get_size(), self.comm_model.Get_rank() + + def get_couple_communicator(self) -> MPI.Comm: + """Generate communicator for ensemble communications + """ + return MPI.COMM_WORLD.Split(self.mype_model, self.mype_ens) + + def is_cpu_consistent(self) -> None: + """Check consistency of number of parallel ensemble tasks + """ + if self.n_modeltasks > self.npes_ens: + # number of parallel tasks is set larger than available PEs *** + self.n_modeltasks = self.npes_ens + if self.mype_ens == 0: + log.logger.warning('!!! Resetting number of parallel ensemble' + ' tasks to total number of PEs!') + + def is_task_consistent(self) -> None: + """Check consistency of number of model tasks + """ + assert self.dim_ens > 0, 'dim_ens (ensemble size) must be > 0' + + # Check consistency with ensemble size + if self.n_modeltasks > self.dim_ens: + # parallel ensemble tasks is set larger than ensemble size + self.n_modeltasks = self.dim_ens + + if self.mype_ens == 0: + log.logger.warning('!!! Resetting number of parallel' + 'ensemble tasks to number of ensemble states!') + + def print_info(self) -> None: + """print parallelization info + """ + # *** local variables *** + # Rank and size in COMM_couple + mype_couple = self.comm_couple.Get_rank() + # Variables for communicator-splitting + color_couple = self.mype_model + 1 + + if self.mype_ens == 0: + log.logger.info('PE configuration:') + log.logger.info('ens filter model couple filterPE') + log.logger.info('rank rank task rank task rank T/F') + log.logger.info('-----------------------------------------------------') + MPI.COMM_WORLD.Barrier() + if self.task_id == 1: + output_str = f'{self.mype_ens}, {self.mype_filter},' \ + f' {self.task_id} {self.mype_model},' \ + f' {color_couple}, {mype_couple}, {self.filter_pe}' + log.logger.info(output_str) + MPI.COMM_WORLD.Barrier() + if self.task_id > 1: + output_str = f'{self.mype_ens}, {self.mype_filter},' \ + f' {self.task_id} {self.mype_model},' \ + f' {color_couple}, {mype_couple}, {self.filter_pe}' + log.logger.info(output_str) + MPI.COMM_WORLD.Barrier() + if self.mype_ens == 0: + log.logger.info('') + + def finalize_parallel(self) -> None: + """Finalize MPI + """ + MPI.COMM_WORLD.Barrier() + MPI.Finalize() diff --git a/pyPDAF/source/example/offline/pdaf_system.py b/pyPDAF/source/example/offline/pdaf_system.py new file mode 100644 index 0000000000000000000000000000000000000000..fb88a394e68d946540c2c36ae88e64c59f17cb90 --- /dev/null +++ b/pyPDAF/source/example/offline/pdaf_system.py @@ -0,0 +1,129 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import numpy as np +import pyPDAF + +import collector +import config +import filter_options +import localisation +import model +import obs_factory +import parallelisation +import prepost_processing +import state_vector + + +class PDAFsystem: + + """PDAF system + + Attributes + ---------- + pe : parallelisation.parallelisation + parallelisation instance + model_grid : model.model_grid + list of model instances + sv : state_vector.state_vector + state vector + local : localisation.localisation + localisation + obs : obs_factory.obs_factory + observation factory + filter_options : filter_options.filter_options + filter options + """ + def __init__(self, pe:parallelisation.Parallelisation, + model_grid:model.ModelGrid) -> None: + self.pe:parallelisation.Parallelisation = pe + self.model_grid:model.ModelGrid = model_grid + + self.filter_options = filter_options.FilterOptions() + self.sv = state_vector.StateVector(model_grid, + dim_ens=pe.dim_ens) + self.local = localisation.Localisation(sv=self.sv) + # here, observation only uses the domain observation of the model ensemble. + # Therefore, only one ensemble member (i.e., model_ens[0]) is passed to obs_factory. + # In a more complicated system, it is possible to have domain class for model, + # in which case only the domain object is required here. + self.obs = obs_factory.ObsFactory(self.pe, + self.model_grid, self.local) + # initial time step + self.steps_for = config.init_step + + def init_pdaf(self, screen:int) -> None: + """constructor + + Parameters + ---------- + screen : int + verbosity of PDAF screen output + """ + filter_param_i = np.array([self.sv.dim_state_p, self.sv.dim_ens], dtype=np.intc) + filter_param_r = np.array([self.filter_options.forget, ]) + status:int = 0 + cltor:collector.Collector = collector.Collector( + self.model_grid, self.pe) + # initialise PDAF filters, communicators, ensemble + # initialise PDAF filters, communicators, ensemble + _, _, status = pyPDAF.init(self.filter_options.filtertype, self.filter_options.subtype, + 0, filter_param_i, len(filter_param_i), filter_param_r, 2, + cltor.init_ens_pdaf, screen) + + assert status == 0, f'ERROR {status} \ + in initialization of PDAF - stopping! \ + (PE f{self.pe.mype_ens})' + + pyPDAF.PDAFomi.init(self.obs.nobs) + + lfilter:int = pyPDAF.PDAF.get_localfilter() + self.local.local_filter = lfilter == 1 + # set local domain on each model process + if self.local.local_filter: + pyPDAF.PDAFomi.init_local() + self.local.set_lim_coords(self.model_grid.nx_p, + self.model_grid.ny_p, self.pe) + + + def assimilate(self) -> None: + """offline assimilation function. + + The put_state_XXX functions execute the DA scheme. + Here, the state vector is read from data in `init_ens_pdaf`. + """ + status:int = 0 + prepost = prepost_processing.Prepost(self.model_grid, self.pe) + pyPDAF.assim_offline(self.obs.init_dim_obs_pdafomi, + self.obs.obs_op_pdafomi, + self.local.init_n_domains_pdaf, + self.local.init_dim_l_pdaf, + self.obs.init_dim_obs_l_pdafomi, + prepost.prepostprocess, status) + + + assert status == 0, f'ERROR {status} in PDAF_put_state' \ + f' - stopping! (PE {self.pe.mype_ens})' + + def finalise(self) -> None: + """finalise PDAF system""" + pyPDAF.PDAF.print_info(11) + if self.pe.mype_ens == 0: + pyPDAF.PDAF.print_info(3) + pyPDAF.PDAF.deallocate() + diff --git a/pyPDAF/source/example/offline/prepost_processing.py b/pyPDAF/source/example/offline/prepost_processing.py new file mode 100644 index 0000000000000000000000000000000000000000..9c96505f83118792e3e7c69e631c38a68001517c --- /dev/null +++ b/pyPDAF/source/example/offline/prepost_processing.py @@ -0,0 +1,167 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import os +import typing + +from mpi4py import MPI +import numpy as np + +import log +import model +import parallelisation + +class Prepost: + """User-supplied functions for pre and post processing of the ensemble. + + Attributes + ---------- + model : `model.model_grid` + model object + pe : `parallelisation.parallelisation` + parallelisation object + ------- + """ + def __init__(self, model_grid: model.ModelGrid, + pe:parallelisation.Parallelisation) -> None: + self.model_grid:model.ModelGrid = model_grid + self.pe:parallelisation.Parallelisation = pe + os.makedirs('outputs_offline', exist_ok=True) + + def get_full_ens(self, dim_p:int, dim_ens:int, ens_p:np.ndarray + ) -> typing.Union[np.ndarray, None]: + """Gather total ensemble from each local processors + """ + if self.pe.npes_filter == 1: + return ens_p + # get total dim + + ## collect full ensemble from domain decomposed ensemble + # collect the length of state vector on each processor (local domain) + all_dim_p:np.ndarray = np.array(self.pe.comm_filter.gather(dim_p, root=0)) + + displacements : np.ndarray | None + send_counts : np.ndarray | None + ens : np.ndarray | None + if self.pe.mype_filter == 0: + # number of elements of the array on each processor + send_counts = all_dim_p*dim_ens + # get the length of the full state vector + dim:int = np.sum(all_dim_p) + # declare the full ensemble + ens = np.zeros(dim*dim_ens) + # displacement of each of the full ensemble + displacements = np.insert(np.cumsum(send_counts), 0, 0)[0:-1] + else: + displacements = None + ens = None + send_counts = None + + # using row-major C order to ensure that + # MPI gathers a continuous row-major array of the model domain + # that is dim_ens number of first element of the state vector + # followed by dim_ens number of the second element of the state vector, etc. + ens_p_send = ens_p.ravel() + self.pe.comm_filter.Gatherv([ens_p_send, MPI.DOUBLE], + [ens, + send_counts, displacements, MPI.DOUBLE], + root=0) + if self.pe.mype_filter == 0: + assert isinstance(ens, np.ndarray), 'ens should be a numpy array' + ens = ens.reshape(dim, dim_ens) + # As a consequence of domain decomposition in nx instead of ny + # (following the PDAF tutorial) + # we need to reorder the array after merging from different processors + displ = np.insert(np.cumsum(all_dim_p), 0, 0)[1:] + ens_tmp = ens[:displ[0]].reshape(self.model_grid.ny, + self.model_grid.nx_p, + dim_ens) + if len(displ) > 0: + for c0, c1 in zip(displ[:-1], displ[1:]): + ens_tmp = np.concatenate([ens_tmp, + ens[c0:c1].reshape(self.model_grid.ny, + self.model_grid.nx_p, + dim_ens)], axis=1) + ens = ens_tmp.reshape(dim, dim_ens) + + return ens + + def initial_process(self, _step:int, dim_p:int, dim_ens:int, _dim_ens_p:int, + _dim_obs_p:int, state_p:np.ndarray, uinv:np.ndarray, + ens_p:np.ndarray, _flag:int) -> tuple[np.ndarray, np.ndarray, np.ndarray]: + """initial processing of the ensemble before it is distributed to model fields + """ + ens = self.get_full_ens(dim_p, dim_ens, ens_p) + if self.pe.mype_filter == 0: + assert isinstance(ens, np.ndarray), 'ens should be a numpy array' + output_str = 'RMS error according to sampled variance: ' \ + f'{np.sqrt(np.mean(np.var(ens, axis=1, ddof=1)))}' + log.logger.info (output_str) + return state_p, uinv, ens_p + + def preprocess(self, step:int, dim_p:int, dim_ens:int, ens_p:np.ndarray) -> None: + """preprocessing of the ensemble before it is used by DA algorithms + """ + ens = self.get_full_ens(dim_p, dim_ens, ens_p) + if self.pe.mype_filter == 0: + assert isinstance(ens, np.ndarray), 'ens should be a numpy array' + output_str = 'Forecast RMS error according to sampled variance:' \ + f' {np.sqrt(np.mean(np.var(ens, axis=1, ddof=1)))}' + log.logger.info (output_str) + os.makedirs('outputs_offline', exist_ok=True) + for i in range(dim_ens): + np.savetxt( + os.path.join( + 'outputs_offline', + f'ens_{i+1}_step{-step}_for.txt' + ), + ens[:, i].reshape(self.model_grid.ny, + self.model_grid.nx) + ) + + def postprocess(self, step:int, dim_p:int, dim_ens:int, ens_p:np.ndarray) -> None: + """initial processing of the ensemble before it is distributed to model fields + """ + ens = self.get_full_ens(dim_p, dim_ens, ens_p) + if self.pe.mype_filter == 0: + assert isinstance(ens, np.ndarray), 'ens should be a numpy array' + output_str = 'Analysis RMS error according to sampled variance:' \ + f' {np.sqrt(np.mean(np.var(ens, axis=1, ddof=1)))}' + log.logger.info (output_str ) + os.makedirs('outputs_offline', exist_ok=True) + for i in range(dim_ens): + np.savetxt( + os.path.join( + 'outputs_offline', + f'ens_{i+1}_step{step}_ana.txt' + ), + ens[:, i].reshape(self.model_grid.ny, + self.model_grid.nx) + ) + + def prepostprocess(self, step:int, dim_p:int, dim_ens:int, _dim_ens_p:int, + _dim_obs_p:int, state_p:np.ndarray, uinv:np.ndarray, + ens_p:np.ndarray, _flag:int + ) -> tuple[np.ndarray, np.ndarray, np.ndarray]: + """pre-/post-processing of the ensemble as user-supplied functions + """ + if step < 0: + self.preprocess(step, dim_p, dim_ens, ens_p) + else: + self.postprocess(step, dim_p, dim_ens, ens_p) + return state_p, uinv, ens_p diff --git a/pyPDAF/source/example/offline/state_vector.py b/pyPDAF/source/example/offline/state_vector.py new file mode 100644 index 0000000000000000000000000000000000000000..1e2a40015cbccb4ec93646cdffc85107f838a2fb --- /dev/null +++ b/pyPDAF/source/example/offline/state_vector.py @@ -0,0 +1,48 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import model + +class StateVector: + + """Dimension of state vector and ensemble size + + Attributes + ---------- + dim_ens : int + ensemble size + dim_state : int + dimension of global state vector + dim_state_p : int + dimension of PE-local state vector + """ + + def __init__(self, model_grid:model.ModelGrid, dim_ens:int + ) -> None: + """AssimilationDimensions constructor + + Parameters + ---------- + model : `model.model_grid` + model grid object + dim_ens : int + ensemble size + """ + self.dim_state_p:int = model_grid.nx_p*model_grid.ny_p + self.dim_state:int = model_grid.nx*model_grid.ny + self.dim_ens:int = dim_ens diff --git a/pyPDAF/source/example/online/collector.py b/pyPDAF/source/example/online/collector.py new file mode 100644 index 0000000000000000000000000000000000000000..c406d10facfe44fa839d6873b53b6a8a7f28c9e6 --- /dev/null +++ b/pyPDAF/source/example/online/collector.py @@ -0,0 +1,81 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import numpy as np + +import config +import model +import parallelisation + + +class Collector: + """This class implements functions where PDAF collects the state vector from model ensemble + + Attributes + ---------- + model: model.model + model instance + """ + def __init__(self, model_t:model.Model, pe: parallelisation.Parallelisation) -> None: + # initialise the model instance + self.model_t: model.Model = model_t + self.pe: parallelisation.Parallelisation = pe + + def init_ens_pdaf(self, _filtertype:int, _dim_p:int, dim_ens:int, + state_p:np.ndarray, uinv:np.ndarray, ens_p:np.ndarray, + status_pdaf:int) -> tuple[np.ndarray, np.ndarray, np.ndarray, int]: + """Here, only ens_p variable matters while dim_p and dim_ens defines the + size of the variables. uinv, state_p are not used in this example. + + status_pdaf is used to handle errors which we will not do it in this example. + """ + # The initial ensemble is read here and will be distributed to + # the model in the PDAF.get_state functtion by a distributor. + + # If your ensemble is read from a restart file, you can simply set this + # function as a dummy function without doing anything + # However, you still need to set a distributor to call PDAF.get_state, which + # does nothing as well. + nx_p:int = self.model_t.nx_p + offset:int = self.pe.mype_filter*nx_p + for i in range(dim_ens): + ens_p[:, i] = np.loadtxt( + config.init_ens_path.format(i=i+1))[:, offset:offset+nx_p].ravel() + return state_p, uinv, ens_p, status_pdaf + + def collect_state(self, _dim_p:int, state_p:np.ndarray) -> np.ndarray: + """PDAF will collect state vector (state_p) from model field. + + + Parameters + ---------- + dim_p: int + Dimension of the state vector on local processor + state_p: np.ndarray + state vector on local processor. + This argument is used by PDAF to form the state vector and ensemble matrix + + Returns + ------- + state_p: np.ndarray + state vector filled with model field + """ + # The [:] treatment ensures that we only change values of + # state_p not the memory address + state_p[:] = self.model_t.field_p.ravel() + return state_p diff --git a/pyPDAF/source/example/online/config.py b/pyPDAF/source/example/online/config.py new file mode 100644 index 0000000000000000000000000000000000000000..8a5620d9af8fabfdb06e4c2d78dac13f353a4557 --- /dev/null +++ b/pyPDAF/source/example/online/config.py @@ -0,0 +1,96 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This is a template file for PDAF configurations. + +The module can be modified to be adjusted to read configparser/YAML/JSON etc. to initialise +options in PDAF and the DA system. +""" +import os + + +# verbosity of the PDAF screen output +screen:int = 2 + +### Filepath ### +# path to initial ensemble, the filename is formatted for different time step +# here a relative path is given +init_ens_path:str = os.path.join('inputs_online', 'ens_{i}.txt') +# path to initial truth +init_truth_path:str = os.path.join('inputs_online', 'true_initial.txt') + + +#### Model configurations #### +# number of grid points in x-direction +nx = 36 +# number of grid points in y-direction +ny = 18 +# initial time step +init_step = 0 +# total number of time steps +nsteps:int = 18 + +#### filter options #### +# number of ensemble members +dim_ens:int = 4 +# number of parallel tasks run simultanously +n_modeltasks:int = 4 +# the type of filter used +# 1=SEIK, 2=EnKF, 3=LSEIK, 4=ETKF, 5=LETKF, 6=ESTKF, 7=LESTKF +# 8=LEnKF, 9=NETF, 10=LNETF, 11=LKNETF, 12=PF, 100=GENOBS, +# 200=3DVar, 0=SEEK +# For a simplified documentation, see:https://pdaf.awi.de/trac/wiki/AvailableOptionsforInitPDAF +# Different DA scheme requires different user-supplied functions +# More information can be found in the PDAF documentation +filtertype:int = 6 +# Variants of each DA scheme check https://pdaf.awi.de/trac/wiki/AvailableOptionsforInitPDAF +subtype:int = 0 +# type of forgetting factor +# - (0) fixed +# - (1) global adaptive +# - (2) local adaptive for LSEIK/LETKF/LESTKF +type_forget:int = 0 +# forgetting factor +forget:float = 1.0 + +#### transformation-related options for Kalman filter (KF) ##### +# type of ensemble transformation +type_trans:int = 0 +# Ways of doing square-root of thetransform matrix +# (0) symmetric square root, (1) Cholesky decomposition +type_sqrt:int = 0 +# (1) to perform incremental updating (only in SEIK/LSEIK!) +incremental:int = 0 +# Definition of factor in covar. matrix used in SEIK +# - (0) for dim_ens^-1 (old SEIK) +# - (1) for (dim_ens-1)^-1 (real ensemble covariance matrix) +# This parameter has also to be set internally in PDAF_init. +covartype:int = 1 +# rank to be considered for inversion of HPH in analysis of EnKF +# (0) for analysis w/o eigendecomposition +# if set to >=ensemble size, it is reset to ensemble size - 1 +rank_analysis_enkf:int = 0 + + +#### localisation options #### +# Type of localization function (0: constant, 1: exponential decay, 2: 5th order polynomial) +loc_weight:int = 3 +# localization cut-off radius in grid points +cradius:float = 6.0 +# Support radius for localization function +sradius:float = cradius diff --git a/pyPDAF/source/example/online/config_obsA.py b/pyPDAF/source/example/online/config_obsA.py new file mode 100644 index 0000000000000000000000000000000000000000..1f46d74461ebe8d0a29974d0942986b0414b5b56 --- /dev/null +++ b/pyPDAF/source/example/online/config_obsA.py @@ -0,0 +1,61 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This is a template file for PDAF configurations. + +The module can be modified to be adjusted to read configparser/YAML/JSON etc. to initialise +options in PDAF and the DA system. +""" +import os + + +# name of the observation +obs_name = 'A' +# path to the observation files +# here a relative path is given +obs_path:str = os.path.join('inputs_online', 'obs_step{i}.txt') +# time steps between observations / assimilation frequency +dtobs:int = 2 +# Observation error standard deviation +rms_obs:float = 0.5 +# Switch for assimilating observation type A +assim:bool = True +# Type of distance computation to use for localization +# It is mandatory for OMI even if we don't use localisation +# 0=Cartesian 1=Cartesian periodic +# details of this property can be seen at +# https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsdisttype +# currently, only PDAF V2.1 is supported +disttype:int = 0 +# Number of coordinates use for distance computation +# Here, it is a 2-dimensional domain +# https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsncoord +ncoord:int = 2 +# nrows depends on the necessity of interpolating +# observations onto model grid +# if nrows = 1, observations are on the model grid points +# when interpolation is required, +# this is the number of grid points required for interpolation. +# For example, nrows = 4 for bi-linear interpolation in 2D, +# and nrows = 8 for 3D linear interpolation. +# https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsid_obs_p +# More information about interpolation is available at +# https://pdaf.awi.de/trac/wiki/OMI_observation_operators#PDAFomi_get_interp_coeff_lin +nrows:int = 1 +# missing value in the observation +missing_value:float = -999. diff --git a/pyPDAF/source/example/online/config_obsB.py b/pyPDAF/source/example/online/config_obsB.py new file mode 100644 index 0000000000000000000000000000000000000000..958ee9a6172137d2f301c1b2be08361b5cd2f484 --- /dev/null +++ b/pyPDAF/source/example/online/config_obsB.py @@ -0,0 +1,61 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This is a template file for PDAF configurations. + +The module can be modified to be adjusted to read configparser/YAML/JSON etc. to initialise +options in PDAF and the DA system. +""" +import os + + +# name of the observation +obs_name = 'B' +# path to the observation files +# here a relative path is given +obs_path:str = os.path.join('inputs_online', 'obsB_step{i}.txt') +# time steps between observations / assimilation frequency +dtobs:int = 2 +# Observation error standard deviation +rms_obs:float = 0.5 +# Switch for assimilating observation type A +assim:bool = False +# Type of distance computation to use for localization +# It is mandatory for OMI even if we don't use localisation +# 0=Cartesian 1=Cartesian periodic +# details of this property can be seen at +# https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsdisttype +# currently, only PDAF V2.1 is supported +disttype:int = 0 +# Number of coordinates use for distance computation +# Here, it is a 2-dimensional domain +# https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsncoord +ncoord:int = 2 +# nrows depends on the necessity of interpolating +# observations onto model grid +# if nrows = 1, observations are on the model grid points +# when interpolation is required, +# this is the number of grid points required for interpolation. +# For example, nrows = 4 for bi-linear interpolation in 2D, +# and 8 for 3D linear interpolation. +# https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsid_obs_p +# More information about interpolation is available at +# https://pdaf.awi.de/trac/wiki/OMI_observation_operators#PDAFomi_get_interp_coeff_lin +nrows:int = 1 +# missing value in the observation +missing_value:float = -999. diff --git a/pyPDAF/source/example/online/distributor.py b/pyPDAF/source/example/online/distributor.py new file mode 100644 index 0000000000000000000000000000000000000000..dfc60aea408ff2f7933dde550cf4c0c92d026be9 --- /dev/null +++ b/pyPDAF/source/example/online/distributor.py @@ -0,0 +1,72 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import numpy as np + +import config +import config_obsA +import config_obsB +import model + +class Distributor: + """This class implements the function where + PDAF distributes ensemble to the model field + + Attributes + ---------- + model: model.model + model instance + """ + def __init__(self, model_t:model.Model) -> None: + # get the model insta + self.model = model_t + + def distribute_state(self, _dim_p:int, state_p:np.ndarray) -> np.ndarray: + """PDAF will distribute state vector (state_p) to model field + + Parameters + ---------- + dim_p: int + Dimension of the state vector on local processor + state_p: np.ndarray + state vector on local processor + + Returns + ------- + state_p: np.ndarray + state vector + """ + self.model.field_p[:] = state_p.reshape(self.model.ny_p, self.model.nx_p) + return state_p + + def next_observation(self, stepnow:int, nsteps:int, + doexit:int, time:float) -> tuple[int, int, float]: + """Providing PDAF the information on the number of model integration steps + to next analysis + """ + # next observation will arrive at `nsteps' steps + nsteps = min(config_obsA.dtobs, config_obsB.dtobs) + # doexit = 0 means that PDAF will continue to distribute state + # to model for further integrations + if stepnow + nsteps >= config.nsteps: + doexit = 1 + else: + doexit = 0 + # model time is the same as time steps + time = float(stepnow) + return nsteps, doexit, time diff --git a/pyPDAF/source/example/online/filter_options.py b/pyPDAF/source/example/online/filter_options.py new file mode 100644 index 0000000000000000000000000000000000000000..1cf31b177cb2c38897a05638450503a6c063bfd2 --- /dev/null +++ b/pyPDAF/source/example/online/filter_options.py @@ -0,0 +1,73 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import config + + +class FilterOptions: + """Here, we provide all filter options + + Attributes + ---------- + filtertype : int + the type of filter used + 1=SEIK, 2=EnKF, 3=LSEIK, 4=ETKF, 5=LETKF, 6=ESTKF, 7=LESTKF + 8=LEnKF, 9=NETF, 10=LNETF, 11=LKNETF, 12=PF, 100=GENOBS, + 200=3DVar, 0=SEEK + For a simplified documentation, see: + https://pdaf.awi.de/trac/wiki/AvailableOptionsforInitPDAF + Different DA scheme requires different user-supplied functions + More information can be found in the PDAF documentation + subtype : int + Variants of each DA scheme check https://pdaf.awi.de/trac/wiki/AvailableOptionsforInitPDAF + type_forget : int + type of forgetting factor + - (0) fixed + - (1) global adaptive + - (2) local adaptive for LSEIK/LETKF/LESTKF + forget : float + forgetting factor + type_trans : int + type of ensemble transformation + type_sqrt : int + type of transform matrix square-root + incremental : int + (1) to perform incremental updating (only in SEIK/LSEIK!) + covartype : int + definition of factor in covar. matrix + rank_analysis_enkf : int + rank to be considered for inversion of HPH in analysis of EnKF + """ + + def __init__(self) -> None: + # Select filter algorithm + self.filtertype:int = config.filtertype + # Subtype of filter algorithm + self.subtype:int = config.subtype + + self.type_forget:int = config.type_forget + # forgeting factor + self.forget:float = config.forget + + # Set other parameters to default values + self.type_trans:int = config.type_trans + self.type_sqrt:int = config.type_sqrt + self.incremental:int = config.incremental + self.covartype:int = config.covartype + + self.rank_analysis_enkf:int = config.rank_analysis_enkf diff --git a/pyPDAF/source/example/online/localisation.py b/pyPDAF/source/example/online/localisation.py new file mode 100644 index 0000000000000000000000000000000000000000..4d9f45fa47ab6445148b1fa6944d16c0bf31e7bc --- /dev/null +++ b/pyPDAF/source/example/online/localisation.py @@ -0,0 +1,146 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import numpy as np + +import pyPDAF + +import config +import log +import parallelisation +import state_vector + + +class Localisation: + """class for localization information and user-supplied functions + + Attributes + ---------- + loc_weight : int + - (0) constant weight of 1 + - (1) exponentially decreasing with sradius + - (2) use 5th-order polynomial + - (3) regulated localization of R with mean error variance + - (4) regulated localization of R with single-point error variance + cradius : float + range for local observation domain + sradius : float + support range for 5th order polynomial + or radius for 1/e for exponential weighting + local_filter : bool + a boolean variable determining whether a local filter is used + by default, it is false and will be later determined by PDAF function + in init_pdaf + sv : state_vector.state_vector + a reference to the state vector object + + Methods + ------- + init_n_domains(self, n_domains:int) + initialise the number of local domains + """ + + def __init__(self, sv:state_vector.StateVector) -> None: + """class constructor + + Parameters + ---------- + sv : 'state_vector.state_vector' + state vector object + """ + self.loc_weight:int = config.loc_weight + self.cradius:float = config.cradius + self.sradius:float = config.sradius + # a boolean variable determining whether a local filter is used + # by default, it is false and will be later determined by PDAF function + # in init_pdaf + self.local_filter:bool = False + # a reference to the state vector object + self.sv:state_vector.StateVector = sv + + def init_n_domains_pdaf(self, _step:int, _ndomains:int) -> int: + """initialize the number of local domains + + Parameters + ---------- + step : int + current time step + ndomains: int + number of local domains on current processor + + Returns + ------- + n_domains_p : int + PE-local number of analysis domains + """ + output_str = f'ndomains: ndomains {self.sv.dim_state_p}' + log.logger.info(output_str) + return self.sv.dim_state_p + + def set_lim_coords(self, nx_p:int, ny_p:int, pe:parallelisation.Parallelisation) -> None: + """set local domain + + Parameters + ---------- + nx_p : int + size of PE-local state vector in x-direction + ny_p : int + size of PE-local state vector in y-direction + pe : 'parallelisation.parallelisation' + parallelization object + """ + # Get offset of local domain in global domain in x-direction + # The the following link for more information + # https://pdaf.awi.de/trac/wiki/PDAFomi_additional_functionality#PDAFomi_set_domain_limits + # note that this is Fortran-based documentation where array index + # starts from 1 + off_nx = nx_p*pe.mype_filter + + lim_coords = np.zeros((2, 2), order='F') + lim_coords[0, 0] = float(off_nx + 1) + lim_coords[0, 1] = float(off_nx + nx_p) + lim_coords[1, 0] = ny_p + lim_coords[1, 1] = 1 + + pyPDAF.PDAFomi.set_domain_limits(lim_coords) + + def init_dim_l_pdaf(self, _step:int, domain_p:int, dim_l:int) -> int: + """initialise the local dimension of PDAF. + + The function returns + the dimension of local state vector + + Parameters + ---------- + step : int + current time step + domain_p : int + index of current local analysis domain + dim_l : int + dimension of local state vector + + Returns + ------- + dim_l : int + dimension of local state vector + """ + # initialize local state dimension + dim_l = 1 + id_lstate_in_pstate:np.ndarray = domain_p*np.ones((dim_l), dtype=np.intc) + pyPDAF.PDAFlocal.set_indices(dim_l, id_lstate_in_pstate) + return dim_l diff --git a/pyPDAF/source/example/online/log.py b/pyPDAF/source/example/online/log.py new file mode 100644 index 0000000000000000000000000000000000000000..26e871aae25ac0aee7d7008adf90ad8473773dd7 --- /dev/null +++ b/pyPDAF/source/example/online/log.py @@ -0,0 +1,27 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import logging +import sys + +logger = logging.getLogger() +logger.setLevel(logging.DEBUG) +ch = logging.StreamHandler() +formatter = logging.Formatter('%(levelname)s: %(message)s') +ch.setFormatter(formatter) +logger.addHandler(ch) \ No newline at end of file diff --git a/pyPDAF/source/example/online/main.py b/pyPDAF/source/example/online/main.py new file mode 100644 index 0000000000000000000000000000000000000000..c123cffb33008167850410aac9d3ffdf571319b7 --- /dev/null +++ b/pyPDAF/source/example/online/main.py @@ -0,0 +1,57 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +""" +import log + +import config +import model +import model_integrator +from parallelisation import Parallelisation +from pdaf_system import PDAFsystem + +def main(): + """main function for the example of online data assimilation""" + pe = Parallelisation(dim_ens=config.dim_ens, n_modeltasks=config.n_modeltasks) + + # Initial Screen output + if pe.mype_ens == 0: + log.logger.info('+++++ PDAF online mode +++++') + log.logger.info('2D model with parallelization') + + # Initialise model + # throughout this example and PDAF, we must assume that each ensemble member + # uses the same domain decomposition. + model_t = model.Model(pe=pe) + model_t.print_info(pe) + + # Initialise model integrator + integrator = model_integrator.ModelIntegrator(model_t) + + # Initialise PDAF system + das = PDAFsystem(pe, model_t) + das.init_pdaf(screen=config.screen) + + integrator.forward(config.nsteps, das) + + das.finalise() + + pe.finalize_parallel() + +if __name__ == '__main__': + main() diff --git a/pyPDAF/source/example/online/model.py b/pyPDAF/source/example/online/model.py new file mode 100644 index 0000000000000000000000000000000000000000..22565c4c6fa76e59ecd2b2deb60d0ab02951fe97 --- /dev/null +++ b/pyPDAF/source/example/online/model.py @@ -0,0 +1,133 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import log +import numpy as np + +import config +import parallelisation + +class Model: + """Model information in PDAF + + Attributes + ---------- + field_p : ndarray + PE-local model field + nx : int + number of grid points in x-direction + nx_p : int + number of grid points in x-direction on local PE + ny : int + number of grid points in y-direction + ny_p : int + number of grid points in y-direction on local PE + current_step : int + current time step + total_steps : int + total number of time steps + """ + + def __init__(self, pe:parallelisation.Parallelisation) -> None: + """constructor + + Parameters + ---------- + nx : ndarray + integer array for grid size in x-dimension + ny : ndarray + integer array for grid size in y-dimension + nt : int + total number of time steps + pe : `parallelization.parallelization` + parallelization object + """ + # model size + self.nx:int = config.nx + self.ny:int = config.ny + # model domain for each CPU (model domain decomposition) + self.nx_p:int + self.ny_p:int + self.nx_p, self.ny_p = self.get_local_domain(pe) + # model time steps + self.total_steps:int = config.nsteps + # model field + self.field_p:np.ndarray = np.zeros((self.ny_p, self.nx_p)) + + def get_local_domain(self, pe:parallelisation.Parallelisation) -> tuple[int, int]: + """Compute local-PE domain size/domain decomposition + + Parameters + ---------- + pe : `parallelization.Parallelisation` + parallelization object + """ + nx_p:int = self.nx + ny_p:int = self.ny + + assert self.nx % pe.npes_model == 0, f'...ERROR: Invalid number of' \ + f'processes: {pe.npes_model}...' + # we parallelise the domain column by column + nx_p = self.nx//pe.npes_model + + return nx_p, ny_p + + def init_field(self, mype_model:int) -> None: + """initialise PE-local model field + + Parameters + ---------- + mype_model : int + rank of the process in model communicator + """ + offset = self.nx_p*mype_model + self.field_p[:] = np.loadtxt(config.init_truth_path)[:, offset:self.nx_p + offset] + + def step(self, pe:parallelisation.Parallelisation, timenow:float) -> None: + """shifting model forward 'integration' + + Parameters + ---------- + pe : `parallelization.parallelization` + parallelization object from example + """ + if pe.task_id == 1 and pe.mype_model == 0: + output_str = f'model step: {timenow}' + log.logger.info(output_str) + + self.field_p = np.roll(self.field_p, 1, axis=0) + + + def print_info(self, pe:parallelisation.Parallelisation) -> None: + """print model info + + Parameters + ---------- + pe : `parallelization.Parallelisation` + parallelization object + """ + if pe.task_id == 1 and pe.mype_model == 0: + log.logger.info('MODEL-side: INITIALIZE PARALLELIZED Shifting model MODEL') + output_str = f'Grid size: {self.nx} x {self.ny}' + log.logger.info(output_str) + output_str = f'Time steps {self.total_steps}' + log.logger.info(output_str) + output_str = f'-- Domain decomposition over {pe.npes_model} PEs' + log.logger.info(output_str) + output_str = f'-- local domain sizes: {self.nx_p} x {self.ny_p}' + log.logger.info(output_str) diff --git a/pyPDAF/source/example/online/model_integrator.py b/pyPDAF/source/example/online/model_integrator.py new file mode 100644 index 0000000000000000000000000000000000000000..284ebc22ac0935a2a203babc3543a5ba13c1431e --- /dev/null +++ b/pyPDAF/source/example/online/model_integrator.py @@ -0,0 +1,65 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import pyPDAF + +import model +import pdaf_system + +class ModelIntegrator: + """This class implements functions where the model ensemble is integrated""" + def __init__(self, model_t: model.Model) -> None: + self.model_t = model_t + + def forward(self, nsteps:int, da_system:pdaf_system.PDAFsystem) -> None: + """This function implements the model integration""" + # When each model task runs one ensemble member, + # i.e. no need to run each ensemble member sequentially, + # we call this full parallel implementation + if da_system.pe.n_modeltasks >= da_system.pe.dim_ens: + self.forward_full_parallel(nsteps, da_system) + else: + self.forward_flexible(da_system) + + def forward_full_parallel(self, nsteps:int, da_system:pdaf_system.PDAFsystem) -> None: + """This function implements the model integration when each model task + (a group of processes with at least one processes) runs one ensemble member, + i.e. no need to run each ensemble member sequentially for this group of processes, + we call this full parallel implementation""" + for j in range(nsteps): + self.model_t.step(da_system.pe, j) + da_system.assimilate() + + def forward_flexible(self, da_system:pdaf_system.PDAFsystem) -> None: + """This function implements the model integration when each model task + runs multiple ensemble members sequentially, i.e. model tasks is smaller than + the ensemble size, flexible implementation""" + timenow = 0. + doexit = 0 + # full DA system integration loop + nsteps_da = da_system.steps_for + while True: + # model integration + for j in range(nsteps_da): + self.model_t.step(da_system.pe, timenow + j) + da_system.assimilate() + nsteps_da, timenow, doexit = pyPDAF.get_fcst_info(nsteps_da, + timenow, + doexit) + if doexit == 1: + break diff --git a/pyPDAF/source/example/online/obs_a.py b/pyPDAF/source/example/online/obs_a.py new file mode 100644 index 0000000000000000000000000000000000000000..e6d7aed176ba80b4a852761a189dbbdd1c1d258d --- /dev/null +++ b/pyPDAF/source/example/online/obs_a.py @@ -0,0 +1,305 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import log + +import numpy as np +import pyPDAF.PDAFomi + +import config_obsA as config +import localisation +import model +import parallelisation + +class ObsA: + + """observation functions for type-A observation + + Attributes + ---------- + i_obs : int + index of the observation type + obs_name : str + name of the current observation type + filename : str + observation filename to be read + dim_obs_p : int + dimension size of the PE-local observation vector + disttype : int + type of distance computation to use for localization + doassim : int + whether to assimilate this observation type + ncoord : int + number of coordinate dimension + nrows : int + number of rows in ocoord_p + dtobs : int + time interval between observations + missing_value : float + missing value in observations (filled by -9999.0 for example) + model_t : model.model + model object + pe : parallelisation.parallelisation + parallelization object + local : localisation.localisation + localisation object + """ + + def __init__(self, i_obs:int, + pe:parallelisation.Parallelisation, + model_t:model.Model, local:localisation.Localisation) -> None: + # i_obs-th observations in the system starting from 1 + self.i_obs:int = i_obs + self.obs_name:str = config.obs_name + assert self.i_obs >= 1, 'observation count must start from 1' + # observation filename + self.filename:str = config.obs_path + # whether this observation is assimilated + self.doassim:int = 0 + # Type of distance computation to use for localization + # It is mandatory for OMI even if we don't use localisation + # 0=Cartesian 1=Cartesian periodic + # details of this property can be seen at + # https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsdisttype + # currently, only PDAF V2.1 is supported + self.disttype:int = config.disttype + # Number of coordinates use for distance computation + # Here, it is a 2-dimensional domain + # https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsncoord + self.ncoord:int = config.ncoord + # nrows depends on the necessity of interpolating + # observations onto model grid + # if nrows = 1, observations are on the model grid points + # when interpolation is required, + # this is the number of grid points required for interpolation. + # For example, nrows = 4 for bi-linear interpolation in 2D, + # and 8 for 3D linear interpolation. + # https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsid_obs_p + # More information about interpolation is available at + # https://pdaf.awi.de/trac/wiki/OMI_observation_operators#PDAFomi_get_interp_coeff_lin + self.nrows:int = config.nrows + self.dtobs = config.dtobs + # specify the missing/filled value of the observations + self.missing_value:float = config.missing_value + self.model:model.Model = model_t + self.pe:parallelisation.Parallelisation = pe + self.local:localisation.Localisation = local + + + def init_dim(self, step:int, dim_obs:int) -> int: + """In PDAFomi, init_dim takes the responsibility to + set the obs_f object, gather information on the observations + including the observation values, observation error, index of + the state vector of the observation, the model domain and + observation coordinate for interpolation, and the distance metric + for localisation. + + + Parameters + ---------- + step : int + current time step + dim_obs : int + dimension of observation vector + + Returns + ------- + int + dimension of observation vector + """ + if self.pe.mype_filter == 0: + output_str = f'Assimilate observations: {self.obs_name}' + log.logger.info(output_str) + + # switch for assimilation of the observation + pyPDAF.PDAFomi.set_doassim(self.i_obs, self.doassim) + # Type of distance computation to use for localization + # It is mandatory for OMI even if we don't use localisation + pyPDAF.PDAFomi.set_disttype(self.i_obs, self.disttype) + # Number of coordinates used for distance computation + pyPDAF.PDAFomi.set_ncoord(self.i_obs, self.ncoord) + + # read observations + filename = self.filename.format(i=step) + obs_field:np.ndarray = np.loadtxt(filename) + # when domain decomposition is used, we only need observations + # within the local model domain + pe_start:int = self.model.nx_p*self.pe.mype_filter + pe_end:int = pe_start + self.model.nx_p + obs_field_p:np.ndarray = obs_field[:, pe_start:pe_end].ravel() + # get total number of valid observations + # a mask for invalid observations + condition:np.ndarray = np.logical_not(np.isclose(obs_field_p, self.missing_value)) + dim_obs_p:int = np.sum(condition) + # obtain the observation vector + obs_p:np.ndarray = obs_field_p[condition] + assert len(obs_p) == dim_obs_p, f'dimension of the observation vector ({len(obs_p)})'\ + f'should be the same as the dim_obs_p ({dim_obs_p})' + + # inverse of observation variance + # here we specify/hard-code the standard deviation of observation is 0.5 + ivar_obs_p:np.ndarray = (1./config.rms_obs/config.rms_obs)*np.ones_like(obs_p) + + # coordinate of each observations + ocoord_p:np.ndarray = np.zeros((self.ncoord, len(obs_p)), order='F') + ocoord_p[0] = np.tile(np.arange(self.model.nx_p) + pe_start, self.model.ny_p)[condition] + ocoord_p[1] = np.repeat(np.arange(self.model.ny_p), self.model.nx_p)[condition] + ocoord_p = ocoord_p + 1. + + + id_obs_p:np.ndarray = np.zeros((self.nrows, len(obs_p)), dtype=np.intc, order='F') + if self.nrows == 1: + # The relationship between observation and state vector + # id_obs_p gives the indices of observed field in state vector + # the index starts from 1 + # The index is based on the full state vector instead of the index in the local domain + # The following code is used because in our example, observations are masked and + # have the same shape as the model grid + state_vector_index_p:np.ndarray = np.arange(1, + self.model.nx_p*self.model.ny_p + 1, + dtype=np.intc) + id_obs_p[0] = state_vector_index_p[condition] + else: + # If interpolation is required for a 2D domain + # id_obs_p has a dimension of (4, dim_obs_p) + # id_obs_p[0] is the index of the grid point in the state vector + # at lower left of the observation + # for more details of the interpolation see: + # https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsid_obs_p + # and + # https://pdaf.awi.de/trac/wiki/OMI_observation_operators#PDAFomi_get_interp_coeff_lin + # In this case, we also need to specify the coefficients for linear interpolation + # using PDAF.omi_get_interp_coeff_lin() function and set icoeff_p to PDAF + icoeff_p:np.ndarray = np.zeros((self.nrows, len(obs_p)), order='F') + for i in range(dim_obs_p): + # here gcoords are set to 0 in this example + # in real applications, it must be the actual coordinates + gcoords:np.ndarray = np.zeros((self.nrows, self.ncoord), order='F') + icoeff_p[:, i] = pyPDAF.PDAFomi.get_interp_coeff_lin(self.nrows, self.ncoord, + gcoords, + ocoord_p[:, i], + icoeff_p[:, i]) + pyPDAF.PDAFomi.set_icoeff_p(self.i_obs, self.nrows, dim_obs_p, icoeff_p) + pyPDAF.PDAFomi.set_id_obs_p(self.i_obs, self.nrows, dim_obs_p, id_obs_p) + + # Type of observation error: (0) Gauss, (1) Laplace + # This is optional + # Without explicit setting, this is 0 + pyPDAF.PDAFomi.set_obs_err_type(self.i_obs, 0) + + # Whether to use (1) global full obs. + # (0) obs. restricted to those relevant for a process domain + # Without explicit setting, this is 1 (using all obs.) + pyPDAF.PDAFomi.set_use_global_obs(self.i_obs, 1) + + # when localisation is used we need to + if self.local.local_filter: + # Size of domain for periodicity for disttype=1 + # (<0 for no periodicity) + domainsize:np.ndarray = np.array([self.model.nx, self.model.ny], dtype=float) + pyPDAF.PDAFomi.set_domainsize(self.i_obs, self.ncoord, domainsize) + + # PDAF need to gather observation information + dim_obs = pyPDAF.PDAFomi.gather_obs(self.i_obs, dim_obs_p, + obs_p, + ivar_obs_p, + ocoord_p, self.ncoord, + self.local.cradius) + + # set covariance localisation for stochastic EnKF/EAKF/EnSRF + if pyPDAF.PDAF.get_local_type() > 1: + dim_p = self.model.nx*self.model.ny + coords_p = np.zeros((2, dim_p), order='F') + offset = self.pe.mype_filter*self.model.nx_p + coords_p[0] = np.tile(np.arange(self.model.nx_p) + \ + offset, self.model.ny_p) + coords_p[1] = np.repeat(np.arange(self.model.ny_p), + self.model.nx_p) + pyPDAF.PDAFomi.set_localize_covar_iso(self.i_obs, dim_p, + self.ncoord, coords_p, + self.local.loc_weight, + self.local.cradius, + self.local.sradius) + + return dim_obs + + def init_dim_obs_l(self, domain_p:int, _step:int, _dim_obs:int, dim_obs_l:int) -> int: + """intialise local observation vector for domain localisation + + Parameters + ---------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs : int + dimension of observation vector + dim_obs_l : int + dimension of local observation vector + + Returns + ------- + dim_obs_l : int + dimension of local observations + """ + # initialize coordinates of local domain + # we use grid point indices as coordinates, + # but could e.g. use meters + coords_l:np.ndarray = np.zeros(self.ncoord) + # we comment out the smart way to calculate the index + # offset = self.pe.mype_filter*self.model.nx_p*self.model.ny_p + # coords_l[0] = domain_p + offset - 1 + # coords_l[0] = coords_l[0]//self.model.ny_p + # coords_l[1] = domain_p + offset - 1 + # coords_l[1] = coords_l[1] - coords_l[0]*self.model.ny_p + + # here is a brutal force way where we simply list all coordinates on each local processor + # and index them based on domain_p + offset:int = self.pe.mype_filter*self.model.nx_p + coords_l[0] = np.tile(np.arange(self.model.nx_p) + offset, self.model.ny_p)[domain_p - 1] + coords_l[1] = np.repeat(np.arange(self.model.ny_p), self.model.nx_p)[domain_p - 1] + coords_l = coords_l + 1. + + return pyPDAF.PDAFomi.init_dim_obs_l_iso(self.i_obs, coords_l, + self.local.loc_weight, + self.local.cradius, + self.local.sradius, dim_obs_l) + + + def obs_op(self, _step:int, state_p:np.ndarray, ostate:np.ndarray) -> np.ndarray: + """convert state vector by observation operator + + Parameters + ---------- + step : int + current time step + state_p : ndarray + PE-local state vector + ostate : ndarray + state vector transformed by identity matrix + + Returns + ------- + ostate : ndarray + state vector transformed by identity matrix + """ + if self.nrows == 1: + return pyPDAF.PDAFomi.obs_op_gridpoint(self.i_obs, state_p, ostate) + + # if interpolation is required + return pyPDAF.PDAFomi.obs_op_interp_lin(self.i_obs, self.nrows, state_p, ostate) diff --git a/pyPDAF/source/example/online/obs_b.py b/pyPDAF/source/example/online/obs_b.py new file mode 100644 index 0000000000000000000000000000000000000000..12c1549f1b25d1b54a3489053715866405dc9b29 --- /dev/null +++ b/pyPDAF/source/example/online/obs_b.py @@ -0,0 +1,287 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import log + +import numpy as np +import pyPDAF.PDAFomi + +import config_obsB as config +import localisation +import model +import parallelisation + +class ObsB: + + """observation functions for type-B observation + Attributes + ---------- + i_obs : int + index of the observation type + obs_name : str + name of the current observation type + filename : str + observation filename to be read + dim_obs_p : int + dimension size of the PE-local observation vector + disttype : int + type of distance computation to use for localization + doassim : int + whether to assimilate this observation type + ncoord : int + number of coordinate dimension + nrows : int + number of rows in ocoord_p + dtobs : int + time interval between observations + missing_value : float + missing value in observations (filled by -9999.0 for example) + model_t : model.model + model object + pe : parallelisation.parallelisation + parallelization object + local : localisation.localisation + localisation object + """ + + def __init__(self, i_obs:int, + pe:parallelisation.Parallelisation, + model_t:model.Model, local:localisation.Localisation) -> None: + # i_obs-th observations in the system starting from 1 + self.i_obs:int = i_obs + self.obs_name:str = config.obs_name + assert self.i_obs >= 1, 'observation count must start from 1' + # observation filename + self.filename:str = config.obs_path + # whether this observation is assimilated + self.doassim:int = 0 + # Type of distance computation to use for localization + # It is mandatory for OMI even if we don't use localisation + # 0=Cartesian 1=Cartesian periodic + # details of this property can be seen at + # https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsdisttype + # currently, only PDAF V2.1 is supported + self.disttype:int = config.disttype + # Number of coordinates use for distance computation + # Here, it is a 2-dimensional domain + # https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsncoord + self.ncoord:int = config.ncoord + # nrows depends on the necessity of interpolating + # observations onto model grid + # if nrows = 1, observations are on the model grid points + # when interpolation is required, + # this is the number of grid points required for interpolation. + # For example, nrows = 4 for bi-linear interpolation in 2D, + # and 8 for 3D linear interpolation. + # https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsid_obs_p + # More information about interpolation is available at + # https://pdaf.awi.de/trac/wiki/OMI_observation_operators#PDAFomi_get_interp_coeff_lin + self.nrows:int = config.nrows + self.dtobs = config.dtobs + # specify the missing/filled value of the observations + self.missing_value:float = config.missing_value + self.model:model.Model = model_t + self.pe:parallelisation.Parallelisation = pe + self.local:localisation.Localisation = local + + + def init_dim(self, step:int, dim_obs:int) -> int: + """In PDAFomi, init_dim takes the responsibility to + set the obs_f object, gather information on the observations + including the observation values, observation error, index of + the state vector of the observation, the model domain and + observation coordinate for interpolation, and the distance metric + for localisation. + + + Parameters + ---------- + step : int + current time step + dim_obs : int + dimension of observation vector + + Returns + ------- + int + dimension of observation vector + """ + if self.pe.mype_filter == 0: + output_str = f'Assimilate observations: {self.obs_name}' + log.logger.info(output_str) + + # switch for assimilation of the observation + pyPDAF.PDAFomi.set_doassim(self.i_obs, self.doassim) + # Type of distance computation to use for localization + # It is mandatory for OMI even if we don't use localisation + pyPDAF.PDAFomi.set_disttype(self.i_obs, self.disttype) + # Number of coordinates used for distance computation + pyPDAF.PDAFomi.set_ncoord(self.i_obs, self.ncoord) + + # read observations + filename = self.filename.format(i=step) + obs_field:np.ndarray = np.loadtxt(filename) + # when domain decomposition is used, we only need observations + # within the local model domain + pe_start:int = self.model.nx_p*self.pe.mype_filter + pe_end:int = pe_start + self.model.nx_p + obs_field_p:np.ndarray = obs_field[:, pe_start:pe_end].ravel() + # get total number of valid observations + # a mask for invalid observations + condition:np.ndarray = np.logical_not(np.isclose(obs_field_p, self.missing_value)) + dim_obs_p:int = np.sum(condition) + # obtain the observation vector + obs_p:np.ndarray = obs_field_p[condition] + assert len(obs_p) == dim_obs_p, f'dimension of the observation vector ({len(obs_p)})'\ + f'should be the same as the dim_obs_p ({dim_obs_p})' + + # inverse of observation variance + # here we specify/hard-code the standard deviation of observation is 0.5 + ivar_obs_p:np.ndarray = (1./config.rms_obs/config.rms_obs)*np.ones_like(obs_p) + + # coordinate of each observations + ocoord_p:np.ndarray = np.zeros((self.ncoord, len(obs_p)), order='F') + ocoord_p[0] = np.tile(np.arange(self.model.nx_p) + pe_start, self.model.ny_p)[condition] + ocoord_p[1] = np.repeat(np.arange(self.model.ny_p), self.model.nx_p)[condition] + ocoord_p = ocoord_p + 1. + + + id_obs_p:np.ndarray = np.zeros((self.nrows, len(obs_p)), dtype=np.intc, order='F') + if self.nrows == 1: + # The relationship between observation and state vector + # id_obs_p gives the indices of observed field in state vector + # the index starts from 1 + # The index is based on the full state vector instead of the index in the local domain + # The following code is used because in our example, observations are masked and + # have the same shape as the model grid + state_vector_index_p:np.ndarray = np.arange(1, + self.model.nx_p*self.model.ny_p + 1, + dtype=np.intc) + id_obs_p[0] = state_vector_index_p[condition] + else: + # If interpolation is required for a 2D domain + # id_obs_p has a dimension of (4, dim_obs_p) + # id_obs_p[0] is the index of the grid point in the state vector + # at lower left of the observation + # for more details of the interpolation see: + # https://pdaf.awi.de/trac/wiki/OMI_observation_modules#thisobsid_obs_p + # and + # https://pdaf.awi.de/trac/wiki/OMI_observation_operators#PDAFomi_get_interp_coeff_lin + # In this case, we also need to specify the coefficients for linear interpolation + # using PDAF.omi_get_interp_coeff_lin() function and set icoeff_p to PDAF + icoeff_p:np.ndarray = np.zeros((self.nrows, len(obs_p)), order='F') + for i in range(dim_obs_p): + # here gcoords are set to 0 in this example + # in real applications, it must be the actual coordinates + gcoords:np.ndarray = np.zeros((self.nrows, self.ncoord), order='F') + icoeff_p[:, i] = pyPDAF.PDAFomi.get_interp_coeff_lin(self.nrows, self.ncoord, + gcoords, ocoord_p[:, i], + icoeff_p[:, i]) + pyPDAF.PDAFomi.set_icoeff_p(self.i_obs, self.nrows, dim_obs_p, icoeff_p) + pyPDAF.PDAFomi.set_id_obs_p(self.i_obs, self.nrows, dim_obs_p, id_obs_p) + + # Type of observation error: (0) Gauss, (1) Laplace + # This is optional + # Without explicit setting, this is 0 + pyPDAF.PDAFomi.set_obs_err_type(self.i_obs, 0) + + # Whether to use (1) global full obs. + # (0) obs. restricted to those relevant for a process domain + # Without explicit setting, this is 1 (using all obs.) + pyPDAF.PDAFomi.set_use_global_obs(self.i_obs, 1) + + # when localisation is used + if self.local.local_filter: + # Size of domain for periodicity for disttype=1 + # (<0 for no periodicity) + domainsize:np.ndarray = np.array([self.model.nx, self.model.ny], dtype=float) + pyPDAF.PDAFomi.set_domainsize(self.i_obs, self.ncoord, domainsize) + + # PDAF need to gather observation information + dim_obs = pyPDAF.PDAFomi.gather_obs(self.i_obs, dim_obs_p, + obs_p, + ivar_obs_p, + ocoord_p, self.ncoord, + self.local.cradius) + return dim_obs + + def init_dim_obs_l(self, domain_p:int, _step:int, _dim_obs:int, dim_obs_l:int) -> int: + """intialise local observation vector for domain localisation + + Parameters + ---------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs : int + dimension of observation vector + dim_obs_l : int + dimension of local observation vector + + Returns + ------- + dim_obs_l : int + dimension of local observations + """ + # initialize coordinates of local domain + # we use grid point indices as coordinates, + # but could e.g. use meters + coords_l:np.ndarray = np.zeros(self.ncoord) + # we comment out the smart way to calculate the index + # offset = self.pe.mype_filter*self.model.nx_p*self.model.ny_p + # coords_l[0] = domain_p + offset - 1 + # coords_l[0] = coords_l[0]//self.model.ny_p + # coords_l[1] = domain_p + offset - 1 + # coords_l[1] = coords_l[1] - coords_l[0]*self.model.ny_p + + # here is a brutal force way where we simply list all coordinates on each local processor + # and index them based on domain_p + offset:int = self.pe.mype_filter*self.model.nx_p + coords_l[0] = np.tile(np.arange(self.model.nx_p) + offset, self.model.ny_p)[domain_p - 1] + coords_l[1] = np.repeat(np.arange(self.model.ny_p), self.model.nx_p)[domain_p - 1] + coords_l = coords_l + 1. + + return pyPDAF.PDAFomi.init_dim_obs_l_iso(self.i_obs, coords_l, + self.local.loc_weight, + self.local.cradius, + self.local.sradius, dim_obs_l) + + + def obs_op(self, _step:int, state_p:np.ndarray, ostate:np.ndarray) -> np.ndarray: + """convert state vector by observation operator + + Parameters + ---------- + step : int + current time step + state_p : ndarray + PE-local state vector + ostate : ndarray + state vector transformed by identity matrix + + Returns + ------- + ostate : ndarray + state vector transformed by identity matrix + """ + if self.nrows == 1: + return pyPDAF.PDAFomi.obs_op_gridpoint(self.i_obs, state_p, ostate) + + # if interpolation is required + return pyPDAF.PDAFomi.obs_op_interp_lin(self.i_obs, self.nrows, state_p, ostate) diff --git a/pyPDAF/source/example/online/obs_factory.py b/pyPDAF/source/example/online/obs_factory.py new file mode 100644 index 0000000000000000000000000000000000000000..9aaf7294af7c43a4a6b94ae519a9f82256dd8f33 --- /dev/null +++ b/pyPDAF/source/example/online/obs_factory.py @@ -0,0 +1,150 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import log + +import numpy as np + +import config_obsA +import config_obsB +import localisation +import model +import obs_a +import obs_b +import parallelisation + +class ObsFactory: + """This class implements all user-supplied functions + used by PDAFomi. These functions are called at every time steps + + Attributes + ---------- + pe : `parallelisation.parallelisation` + parallelization object + model : `model.model` + model object + local : `localisation.localisation` + localisation object + obs_list : list + list of observation types + nobs : int + total number of observation types + """ + def __init__(self, pe:parallelisation.Parallelisation, + model_t:model.Model, local:localisation.Localisation) -> None: + # Initialise observations + self.pe: parallelisation.Parallelisation = pe + self.model:model.Model = model_t + self.local:localisation.Localisation = local + self.obs_list:list = [] + self.nobs:int = 0 + if config_obsA.assim: + self.nobs += 1 + self.obs_list.append(obs_a.ObsA(self.nobs, self.pe, self.model, self.local) + ) + if config_obsB.assim: + self.nobs += 1 + self.obs_list.append(obs_b.ObsB(self.nobs, self.pe, self.model, self.local) + ) + output_str = f'total number of observation types: {self.nobs}' + log.logger.info (output_str) + + def init_dim_obs_pdafomi(self, step:int, dim_obs:int) -> int: + """initialise observation dimensions + + Parameters + ---------- + step : int + current time step + dim_obs : int + dimension of observation vector + + Returns + ------- + dim_obs : int + dimension of observation vector + """ + # it is possibly useful to add some checks on obs.doassim here + # For example, set obs.doassim = 0 if one type of observation + # is not used for this particular step. + for obs in self.obs_list: + if step % obs.dtobs == 0: + obs.doassim = 1 + # calculate the dimension of full observation vector + dim_obs = 0 + for obs in self.obs_list: + if obs.doassim == 1: + dim_obs_o:int = obs.init_dim(step, dim_obs) + dim_obs = dim_obs + dim_obs_o + + return dim_obs + + def obs_op_pdafomi(self, step:int, _dim_p:int, _dim_obs_p:int, + state_p:np.ndarray, ostate:np.ndarray) -> np.ndarray: + """turn state vector to observation space + + Parameters + ---------- + step : int + current time step + dim_p: int + dimension of state vector on local processor + dim_obs_p: int + dimension of observation vector on local processor + state_p : ndarray + local PE state vector + ostate : ndarray + state vector in obs space + + Returns + ------- + ostate : ndarray + state vector in obs space + """ + + for obs in self.obs_list: + if obs.doassim == 1: + ostate = obs.obs_op(step, state_p, ostate) + return ostate + + def init_dim_obs_l_pdafomi(self, domain_p:int, step:int, dim_obs:int, dim_obs_l:int) -> int: + """initialise number of observations in each local domain + + Parameters + ---------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs : int + dimension of observation vector + dim_obs_l : int + dimension of local observation vector + + Returns + ------- + dim_obs_l : int + dimension of local observation vector + """ + dim_obs_l = 0 + for obs in self.obs_list: + if obs.doassim == 1: + dim_obs_l_o:int = obs.init_dim_obs_l(domain_p, step, dim_obs, dim_obs_l) + dim_obs_l = dim_obs_l + dim_obs_l_o + + return dim_obs_l diff --git a/pyPDAF/source/example/online/parallelisation.py b/pyPDAF/source/example/online/parallelisation.py new file mode 100644 index 0000000000000000000000000000000000000000..4d469380c86308dad623cb2faf8014e5b4fde658 --- /dev/null +++ b/pyPDAF/source/example/online/parallelisation.py @@ -0,0 +1,301 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import log + +from mpi4py import MPI +import numpy as np + +import pyPDAF + + +class Parallelisation: + + """Summary + + Attributes + ---------- + n_modeltasks : int + number of model tasks run in parallel + dim_ens : int + total ensemble size + + comm_ens : `MPI.Comm` + ensemble communicator + npes_ens : int + number of global PEs + mype_ens : int + rank of ens communicator + local_npes_model : int + number of model PEs used by each model task + task_id : int + model task id of the current processor + comm_model : `MPI.Comm` + model communicator + npes_model : int + number of model PEs + mype_model : int + rank of model communicator + dim_ens_l : int + number of ensemble members per model task + This is the same as dim_ens//n_modeltasks + for each model task in parallel + all_dim_ens_l : np.ndarray + number of ensemble members across all PEs. + filterpe : bool + whether the PE is used for filter + comm_filter : `MPI.Comm` + filter communicator + npes_filter : int + number of filter PEs + mype_filter : int + rank of filter communicator + comm_couple : `MPI.Comm` + model and filter coupling communicator + """ + + def __init__(self, dim_ens:int, n_modeltasks:int) -> None: + """Init the parallization required by PDAF + + Parameters + ---------- + dim_ens : TYPE + Description + n_modeltasks : int + Number of model tasks/ ensemble size + This parameter should be the same + as the number of PEs + """ + + # number of model tasks run in parallel + # this is limited by the number of processors + self.n_modeltasks:int = n_modeltasks + # total number of ensemble members. This can be larger than + # number of parallel model tasks where the 'flexible' implementation + # is used + self.dim_ens:int = dim_ens + + # Initialize model communicator, its size and the process rank + # Here the same as for MPI_COMM_WORLD + self.comm_ens:MPI.Comm + self.npes_ens:int + self.mype_ens:int + self.comm_ens, self.npes_ens, self.mype_ens = self.init_parallel() + + self.is_task_consistent() + self.is_cpu_consistent() + + # Initialize communicators for ensemble evaluations + if self.mype_ens == 0: + log.logger.info('Initialize communicators for assimilation with PDAF') + + # get the number of processors used by each model task + self.local_npes_model:np.ndarray = self.get_processor_per_model() + self.task_id:int = self.get_task_id() + # get model communicator + self.comm_model:MPI.Comm + self.npes_model:int + self.mype_model:int + self.comm_model, self.npes_model, self.mype_model = self.get_model_communicator() + + # local ensemble member of each model task/processors. + # When dim_ens > n_modeltasks, some processors/model tasks + # run dim_ens_l number of members sequentially. + # When n_modeltasks = dim_ens, dim_ens_l = 1 + # Here dim_ens_l is the ensemble size for current model task + # all_dim_ens_l is the ensemble size for all task ids. + # self.dim_ens_l:int + # self.all_dim_ens_l:np.ndarray + # self.dim_ens_l, self.all_dim_ens_l = self.get_dim_ens_l() + + output_str = f'MODEL: mype(w)= {self.mype_ens}' \ + f'; model task: {self.task_id}' \ + f'; mype(m)= {self.mype_model}' \ + f'; npes(m)= {self.npes_model}' + log.logger.info(output_str) + + # Generate communicator for filter + self.filter_pe:bool + self.comm_filter:MPI.Comm + self.npes_filter:int + self.mype_filter:int + self.filter_pe, self.comm_filter = self.get_filter_communicator() + self.npes_filter, self.mype_filter = self.get_filter_communicator_size_rank() + + # Generate communicators for communication + self.comm_couple:MPI.Comm = self.get_couple_communicator() + + self.print_info() + + status = 0 + status = pyPDAF.set_parallel(self.comm_ens.py2f(), self.comm_model.py2f(), + self.comm_filter.py2f(), self.comm_couple.py2f(), + self.task_id, self.n_modeltasks, self.filter_pe, + status) + + def init_parallel(self) -> tuple[MPI.Comm, int, int]: + """Initialize MPI + + Routine to initialize MPI. + + Here, we also return the communicator for the full ensemble + as well as its size and the rank of the current processor in + the communicator. + + In this simple example, the full ensemble communicator is the + MPI_COMM_WORLD. + """ + if not MPI.Is_initialized(): + MPI.Init() + + return MPI.COMM_WORLD, MPI.COMM_WORLD.Get_size(), MPI.COMM_WORLD.Get_rank() + + def get_processor_per_model(self) -> np.ndarray: + """Store # PEs per ensemble + used for info on PE 0 and for generation + of model communicators on other Pes + """ + + local_npes_model:np.ndarray = np.zeros(self.n_modeltasks, dtype=int) + + local_npes_model[:] = np.floor( + self.npes_ens/self.n_modeltasks) + + size:int = self.npes_ens \ + - self.n_modeltasks * local_npes_model[0] + local_npes_model[:size] = local_npes_model[:size] + 1 + + return local_npes_model + + def get_task_id(self) -> int: + """get model communicator + Generate communicators for model runs + (Split COMM_ENSEMBLE) + """ + pe_index:np.ndarray = np.cumsum(self.local_npes_model, dtype=int) + # task id of the current processor + task_id:int = np.arange(self.n_modeltasks)[pe_index <= + self.mype_ens + self.local_npes_model[0]][-1] + 1 + + return task_id + + def get_model_communicator(self) -> tuple[MPI.Comm, int, int]: + """get model PE rank and size + """ + comm_model = MPI.COMM_WORLD.Split(self.task_id, self.mype_ens) + return comm_model, comm_model.Get_size(), comm_model.Get_rank() + + def get_dim_ens_l(self) -> tuple[int, np.ndarray]: + """obtain number of ensemble members for each model task + + This means that each model task has to run dim_ens_l + number of ensemble members sequentially + """ + # number of ensemble for each model task + dim_ens_l:int = self.dim_ens//self.n_modeltasks + residual:int = self.dim_ens - dim_ens_l*self.n_modeltasks + # number of ensmeble members across all PEs + # e.g. self.all_dim_ens_l[0] is the ensemble size on the first PE + # and self.all_dim_ens_l[-1] is the ensemble size on the last PE + all_dim_ens_l:np.ndarray = dim_ens_l*np.ones(self.n_modeltasks, dtype=int) + all_dim_ens_l[:residual] += 1 + # number of tasks on local PE + dim_ens_l = all_dim_ens_l[self.task_id - 1] + if self.mype_ens == 0: + output_str = f'number of Ens per PE {all_dim_ens_l}' + log.logger.debug (output_str) + return dim_ens_l, all_dim_ens_l + + def get_filter_communicator(self) -> tuple[bool, MPI.Comm]: + """Generate communicator for filter + """ + # filter is only conducted in the first model task + filterpe:bool = True if self.task_id == 1 else False + my_color:int = self.task_id if filterpe else MPI.UNDEFINED + comm_filter:MPI.Comm = MPI.COMM_WORLD.Split(my_color, self.mype_ens) + return filterpe, comm_filter + + def get_filter_communicator_size_rank(self) -> tuple[int, int]: + """get filter PE rank and size which should be same as model size and rank + """ + return self.comm_model.Get_size(), self.comm_model.Get_rank() + + def get_couple_communicator(self) -> MPI.Comm: + """Generate communicator for ensemble communications + """ + return MPI.COMM_WORLD.Split(self.mype_model, self.mype_ens) + + def is_cpu_consistent(self) -> None: + """Check consistency of number of parallel ensemble tasks + """ + if self.n_modeltasks > self.npes_ens: + # number of parallel tasks is set larger than available PEs *** + self.n_modeltasks = self.npes_ens + if self.mype_ens == 0: + log.logger.warning('!!! Resetting number of parallel ensemble' + ' tasks to total number of PEs!') + + def is_task_consistent(self) -> None: + """Check consistency of number of model tasks + """ + assert self.dim_ens > 0, 'dim_ens (ensemble size) must be > 0' + + # Check consistency with ensemble size + if self.n_modeltasks > self.dim_ens: + # parallel ensemble tasks is set larger than ensemble size + self.n_modeltasks = self.dim_ens + + if self.mype_ens == 0: + log.logger.warning('!!! Resetting number of parallel' + 'ensemble tasks to number of ensemble states!') + + def print_info(self) -> None: + """print parallelization info + """ + # *** local variables *** + # Rank and size in COMM_couple + mype_couple = self.comm_couple.Get_rank() + # Variables for communicator-splitting + color_couple = self.mype_model + 1 + + if self.mype_ens == 0: + log.logger.info('PE configuration:') + log.logger.info('ens filter model couple filterPE') + log.logger.info('rank rank task rank task rank T/F') + log.logger.info('-----------------------------------------------------') + MPI.COMM_WORLD.Barrier() + if self.task_id == 1: + output_str = f'{self.mype_ens}, {self.mype_filter},' \ + f' {self.task_id} {self.mype_model},' \ + f' {color_couple}, {mype_couple}, {self.filter_pe}' + log.logger.info(output_str) + MPI.COMM_WORLD.Barrier() + if self.task_id > 1: + output_str = f'{self.mype_ens}, {self.mype_filter},' \ + f' {self.task_id} {self.mype_model},' \ + f' {color_couple}, {mype_couple}, {self.filter_pe}' + log.logger.info(output_str) + MPI.COMM_WORLD.Barrier() + if self.mype_ens == 0: + log.logger.info('') + + def finalize_parallel(self) -> None: + """Finalize MPI + """ + MPI.COMM_WORLD.Barrier() + MPI.Finalize() diff --git a/pyPDAF/source/example/online/pdaf_system.py b/pyPDAF/source/example/online/pdaf_system.py new file mode 100644 index 0000000000000000000000000000000000000000..520e10411477c09d5a744d81a396bca0737fb50f --- /dev/null +++ b/pyPDAF/source/example/online/pdaf_system.py @@ -0,0 +1,134 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import numpy as np + +import collector +import config +import distributor +import filter_options +import localisation +import model +import obs_factory +import parallelisation +import prepost_processing +import state_vector + +import pyPDAF + +class PDAFsystem: + + """PDAF system + + Attributes + ---------- + pe : parallelisation.parallelisation + parallelisation instance + model_ens : list[model.model] + list of model instances + sv : state_vector.state_vector + state vector + local : localisation.localisation + localisation + obs : obs_factory.obs_factory + observation factory + filter_options : filter_options.filter_options + filter options + """ + def __init__(self, pe:parallelisation.Parallelisation, model_ens:model.Model) -> None: + self.pe = pe + self.model_ens = model_ens + + self.filter_options = filter_options.FilterOptions() + self.sv = state_vector.StateVector(model_ens, dim_ens=pe.dim_ens) + self.local = localisation.Localisation(sv=self.sv) + # here, observation only uses the domain observation of the model ensemble. + # In a more complicated system, it is possible to have domain class for model, + # in which case only the domain object is required here. + self.obs = obs_factory.ObsFactory(self.pe, self.model_ens, self.local) + # initial time step + self.steps_for = config.init_step + self.cltor = collector.Collector(self.model_ens, self.pe) + self.prepost = prepost_processing.Prepost(self.model_ens, self.pe) + self.dist = distributor.Distributor(self.model_ens) + + def init_pdaf(self, screen:int) -> None: + """constructor + + Parameters + ---------- + screen : int + verbosity of PDAF screen output + """ + filter_param_i = np.array([self.sv.dim_state_p, self.sv.dim_ens], dtype=np.intc) + filter_param_r = np.array([self.filter_options.forget, ]) + + status:int = 0 + # initialise PDAF filters, communicators, ensemble + _, _, status = pyPDAF.init(self.filter_options.filtertype, self.filter_options.subtype, + 0, filter_param_i, 2, filter_param_r, 1, + self.cltor.init_ens_pdaf, screen) + + assert status == 0, f'ERROR {status} \ + in initialization of PDAF - stopping! \ + (PE f{self.pe.mype_ens})' + + pyPDAF.PDAFomi.init(self.obs.nobs) + lfilter = pyPDAF.PDAF.get_localfilter() + self.local.local_filter = lfilter == 1 + # set local domain on each model process + if self.local.local_filter: + pyPDAF.PDAFomi.init_local() + self.local.set_lim_coords(self.model_ens.nx_p, self.model_ens.ny_p, self.pe) + + # PDAF distribute the initial ensemble to model field + status = pyPDAF.init_forecast(self.dist.next_observation, + self.dist.distribute_state, + self.prepost.initial_process, + status) + + def assimilate(self) -> None: + """Calling assimilation function of PDAF + + Parameters + ---------- + i : int + index of the ensemble in current model task. + """ + status:int = 0 + + status = \ + pyPDAF.assimilate(self.cltor.collect_state, + self.dist.distribute_state, + self.obs.init_dim_obs_pdafomi, + self.obs.obs_op_pdafomi, + self.local.init_n_domains_pdaf, + self.local.init_dim_l_pdaf, + self.obs.init_dim_obs_l_pdafomi, + self.prepost.prepostprocess, + self.dist.next_observation, status) + + assert status == 0, f'ERROR {status} in PDAF_put_state - stopping! (PE {self.pe.mype_ens})' + + def finalise(self) -> None: + """finalise PDAF + """ + pyPDAF.PDAF.print_info(11) + if self.pe.mype_ens == 0: + pyPDAF.PDAF.print_info(3) + pyPDAF.deallocate() diff --git a/pyPDAF/source/example/online/prepost_processing.py b/pyPDAF/source/example/online/prepost_processing.py new file mode 100644 index 0000000000000000000000000000000000000000..b46143f62a99c6f1c121e00faa002bbfe658a8cc --- /dev/null +++ b/pyPDAF/source/example/online/prepost_processing.py @@ -0,0 +1,151 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import os +import typing + +from mpi4py import MPI +import numpy as np + +import log +import model +import parallelisation + +class Prepost: + """User-supplied functions for pre and post processing of the ensemble. + + Attributes + ---------- + model : `model.model` + model object + pe : `parallelisation.parallelisation` + parallelisation object + ------- + """ + def __init__(self, model_t: model.Model, pe:parallelisation.Parallelisation) -> None: + self.model:model.Model = model_t + self.pe:parallelisation.Parallelisation = pe + os.makedirs('outputs_online', exist_ok=True) + + def get_full_ens(self, dim_p:int, dim_ens:int, ens_p:np.ndarray + ) -> typing.Union[np.ndarray, None]: + """Gather total ensemble from each local processors + """ + if self.pe.npes_filter == 1: + return ens_p + # get total dim + + ## collect full ensemble from domain decomposed ensemble + # collect the length of state vector on each processor (local domain) + all_dim_p:np.ndarray = np.array(self.pe.comm_filter.gather(dim_p, root=0)) + + displacements : np.ndarray | None + send_counts : np.ndarray | None + ens : np.ndarray | None + if self.pe.mype_filter == 0: + # number of elements of the array on each processor + send_counts = all_dim_p*dim_ens + # get the length of the full state vector + dim:int = np.sum(all_dim_p) + # declare the full ensemble + ens = np.zeros(dim*dim_ens) + # displacement of each of the full ensemble + displacements = np.insert(np.cumsum(send_counts), 0, 0)[0:-1] + else: + displacements = None + ens = None + send_counts = None + + # using row-major C order to ensure that + # MPI gathers a continuous row-major array of the model domain + # that is dim_ens number of first element of the state vector + # followed by dim_ens number of the second element of the state vector, etc. + ens_p_send = ens_p.ravel() + self.pe.comm_filter.Gatherv([ens_p_send, MPI.DOUBLE], + [ens, + send_counts, displacements, MPI.DOUBLE], + root=0) + if self.pe.mype_filter == 0: + assert isinstance(ens, np.ndarray), 'ens should be a numpy array' + ens = ens.reshape(dim, dim_ens) + # As a consequence of domain decomposition in nx instead of ny + # (following the PDAF tutorial) + # we need to reorder the array after merging from different processors + displ = np.insert(np.cumsum(all_dim_p), 0, 0)[1:] + ens_tmp = ens[:displ[0]].reshape(self.model.ny, self.model.nx_p, dim_ens) + if len(displ) > 0: + for c0, c1 in zip(displ[:-1], displ[1:]): + ens_tmp = np.concatenate([ens_tmp, + ens[c0:c1].reshape(self.model.ny, self.model.nx_p, dim_ens)], axis=1) + ens = ens_tmp.reshape(dim, dim_ens) + + return ens + + def initial_process(self, _step:int, dim_p:int, dim_ens:int, _dim_ens_p:int, + _dim_obs_p:int, state_p:np.ndarray, uinv:np.ndarray, + ens_p:np.ndarray, _flag:int) -> tuple[np.ndarray, np.ndarray, np.ndarray]: + """initial processing of the ensemble before it is distributed to model fields + """ + ens = self.get_full_ens(dim_p, dim_ens, ens_p) + if self.pe.mype_filter == 0: + assert isinstance(ens, np.ndarray), 'ens should be a numpy array' + output_str = 'RMS error according to sampled variance:' \ + f' {np.sqrt(np.mean(np.var(ens, axis=1, ddof=1)))}' + log.logger.info (output_str) + return state_p, uinv, ens_p + + def preprocess(self, step:int, dim_p:int, dim_ens:int, ens_p:np.ndarray) -> None: + """preprocessing of the ensemble before it is used by DA algorithms + """ + ens = self.get_full_ens(dim_p, dim_ens, ens_p) + if self.pe.mype_filter == 0: + assert isinstance(ens, np.ndarray), 'ens should be a numpy array' + output_str = f'Forecast RMS error according to sampled variance:' \ + f' {np.sqrt(np.mean(np.var(ens, axis=1, ddof=1)))}' + log.logger.info (output_str) + os.makedirs('outputs_online', exist_ok=True) + for i in range(dim_ens): + np.savetxt(os.path.join('outputs_online', + f'ens_{i+1}_step{-step}_for.txt') , + ens[:, i].reshape(self.model.ny, self.model.nx) ) + + def postprocess(self, step:int, dim_p:int, dim_ens:int, ens_p:np.ndarray) -> None: + """initial processing of the ensemble before it is distributed to model fields + """ + ens = self.get_full_ens(dim_p, dim_ens, ens_p) + if self.pe.mype_filter == 0: + assert isinstance(ens, np.ndarray), 'ens should be a numpy array' + output_str = 'Analysis RMS error according to sampled variance:' \ + f' {np.sqrt(np.mean(np.var(ens, axis=1, ddof=1)))}' + log.logger.info (output_str) + os.makedirs('outputs_online', exist_ok=True) + for i in range(dim_ens): + np.savetxt(os.path.join('outputs_online', + f'ens_{i+1}_step{step}_ana.txt'), + ens[:, i].reshape(self.model.ny, self.model.nx) ) + + def prepostprocess(self, step:int, dim_p:int, dim_ens:int, _dim_ens_p:int, + _dim_obs_p:int, state_p:np.ndarray, uinv:np.ndarray, + ens_p:np.ndarray, _flag:int) -> tuple[np.ndarray, np.ndarray, np.ndarray]: + """pre-/post-processing of the ensemble as user-supplied functions + """ + if step < 0: + self.preprocess(step, dim_p, dim_ens, ens_p) + else: + self.postprocess(step, dim_p, dim_ens, ens_p) + return state_p, uinv, ens_p diff --git a/pyPDAF/source/example/online/state_vector.py b/pyPDAF/source/example/online/state_vector.py new file mode 100644 index 0000000000000000000000000000000000000000..0144cf592542920792019d7788b0c073dcf28e7f --- /dev/null +++ b/pyPDAF/source/example/online/state_vector.py @@ -0,0 +1,47 @@ +"""This file is part of pyPDAF + +Copyright (C) 2022 University of Reading and +National Centre for Earth Observation + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import model + +class StateVector: + + """Dimension of state vector and ensemble size + + Attributes + ---------- + dim_ens : int + ensemble size + dim_state : int + dimension of global state vector + dim_state_p : int + dimension of PE-local state vector + """ + + def __init__(self, model_t:model.Model, dim_ens:int) -> None: + """AssimilationDimensions constructor + + Parameters + ---------- + model_t : `model.Model` + model object + dim_ens : int + ensemble size + """ + self.dim_state_p:int = model_t.nx_p*model_t.ny_p + self.dim_state:int = model_t.nx*model_t.ny + self.dim_ens:int = dim_ens diff --git a/pyPDAF/source/meson.build b/pyPDAF/source/meson.build new file mode 100644 index 0000000000000000000000000000000000000000..dda8293d0ec561ae3830afc2619eba159604b2e2 --- /dev/null +++ b/pyPDAF/source/meson.build @@ -0,0 +1,338 @@ +project('pyPDAF', 'cython', 'fortran', 'c', version: '1.0.4', + meson_version: '>=1.5.0', default_options: ['b_asneeded=false']) + +fs = import('fs') + +py_mod = import('python') +python = py_mod.find_installation(pure: false) +dep_py = python.dependency() + +cc = meson.get_compiler('c') +ff = meson.get_compiler('fortran') + +mpimod = get_option('mpi_mod') + +if host_machine.system() == 'windows' + mpi = dependency('mpi', language : 'fortran', required: true) +else + mpi = dependency('', language : 'fortran', required: false) +endif + +blas_lib = get_option('blas_lib') +incdirs = get_option('incdirs') +libdirs = get_option('libdirs') + +blas_lib_dep = [] +foreach lib : blas_lib + blas_lib_dep += ff.find_library(lib, dirs:libdirs, required : true) +endforeach + +blas_dep = declare_dependency( + dependencies: blas_lib_dep, + include_directories: incdirs, +) + +c_cython_args = cc.get_supported_arguments(['/O2', '/GL', '-O3'], checked: 'warn') +cython_args = ['-Xboundscheck=False', '-Xbinding=False', '-Xwraparound=False', '-Xinitializedcheck=False'] + +is_flang = ff.get_id() in ['llvm-flang', 'flang', 'flang-new'] +fruntime_dep = dependency('', required : false) +if is_flang + fortran_ext_args = ['-O2', ] + fortran_args = ['-O2', '-fdefault-real-8', '-DUSE_PDAF'] # no probe + fortran_runtime_lib = ff.find_library('FortranRuntime', dirs: libdirs, required : true) + fortran_decimal_lib = ff.find_library('FortranDecimal', dirs: libdirs, required : true) + fruntime_dep = declare_dependency( + dependencies: [fortran_runtime_lib, fortran_decimal_lib], + ) +else + fortran_args = ff.get_supported_arguments( + ['-O3', '-fdefault-real-8', '-DUSE_PDAF'], checked: 'warn') + fortran_ext_args = ff.get_supported_arguments( + ['-O3', ], checked: 'warn') + # fortran_args = ff.get_supported_arguments([ + # '-O0','-g','-fcheck=all','-fbacktrace','-Wall','-Wextra', + # '-fdefault-real-8','-DUSE_PDAF' + # ], checked: 'warn') +endif + +incdir_numpy = run_command(python, + ['-c', 'import os; os.chdir(".."); import numpy; print(numpy.get_include())'], + check : true +).stdout().strip() + +# For conda-build, in MacOS, ISO_Fortran_binding.h is installed by gfortran instead of +# clang. However, the c code generated by cython needs other header files +# which are different from those provided by gfortran. +# So we copy ISO_Fortran_binding.h to the source tree. +# This is a workaround. +# If you have a better solution, please let me know. +incdir_f_header = '.' +if host_machine.system() == 'darwin' + incdir_f_header = run_command(ff.cmd_array() + ['-print-file-name=include'], + check: true).stdout().strip() + run_command('cp', incdir_f_header / 'ISO_Fortran_binding.h', meson.source_root()/'src/pyPDAF/PDAFomi/ISO_Fortran_binding.h') + run_command('cp', incdir_f_header / 'ISO_Fortran_binding.h', meson.source_root()/'src/pyPDAF/PDAF/ISO_Fortran_binding.h') + run_command('cp', incdir_f_header / 'ISO_Fortran_binding.h', meson.source_root()/'src/pyPDAF/PDAF3/ISO_Fortran_binding.h') + run_command('cp', incdir_f_header / 'ISO_Fortran_binding.h', meson.source_root()/'src/pyPDAF/PDAFlocal/ISO_Fortran_binding.h') + run_command('cp', incdir_f_header / 'ISO_Fortran_binding.h', meson.source_root()/'src/pyPDAF/PDAFlocalomi/ISO_Fortran_binding.h') +endif + +# due to a bug in install_rpath, we need to put rpath to link args +# $ORIGIN for Linux, @loader_path for MacOS +link_args = [ + '-Wl,-rpath,$ORIGIN/../', + '-Wl,-rpath,@loader_path/../', +] + +fortran_sources = files('PDAF/src/PDAF3_init.F90', + 'PDAF/src/PDAF3_assimilate_3dvars.F90', + 'PDAF/src/PDAF3_assimilate_3dvars_nondiagR.F90', + 'PDAF/src/PDAF3_assimilate_ens.F90', + 'PDAF/src/PDAF3_assimilate_ens_nondiagR.F90', + 'PDAF/src/PDAF3_assim_offline_3dvars.F90', + 'PDAF/src/PDAF3_assim_offline_3dvars_nondiagR.F90', + 'PDAF/src/PDAF3_assim_offline_ens.F90', + 'PDAF/src/PDAF3_assim_offline_ens_nondiagR.F90', + 'PDAF/src/PDAF_3dvar_analysis_cvt.F90', + 'PDAF/src/PDAF_3dvar.F90', + 'PDAF/src/PDAF_3dvar_optim.F90', + 'PDAF/src/PDAF_3dvar_update.F90', + 'PDAF/src/PDAF3_put_state_3dvars.F90', + 'PDAF/src/PDAF3_put_state_3dvars_nondiagR.F90', + 'PDAF/src/PDAF3_put_state_ens.F90', + 'PDAF/src/PDAF3_put_state_ens_nondiagR.F90', + 'PDAF/src/PDAF_analysis_utils.F90', + 'PDAF/src/PDAF_assimilate_3dvar.F90', + 'PDAF/src/PDAF_assimilate_en3dvar_estkf.F90', + 'PDAF/src/PDAF_assimilate_en3dvar_lestkf.F90', + 'PDAF/src/PDAF_assimilate_enkf.F90', + 'PDAF/src/PDAF_assimilate_ensrf.F90', + 'PDAF/src/PDAF_assimilate_estkf.F90', + 'PDAF/src/PDAF_assimilate_etkf.F90', + 'PDAF/src/PDAF_assimilate_hyb3dvar_estkf.F90', + 'PDAF/src/PDAF_assimilate_hyb3dvar_lestkf.F90', + 'PDAF/src/PDAF_assimilate_lenkf.F90', + 'PDAF/src/PDAF_assimilate_lestkf.F90', + 'PDAF/src/PDAF_assimilate_letkf.F90', + 'PDAF/src/PDAF_assimilate_lknetf.F90', + 'PDAF/src/PDAF_assimilate_lnetf.F90', + 'PDAF/src/PDAF_assimilate_lseik.F90', + 'PDAF/src/PDAF_assimilate_netf.F90', + 'PDAF/src/PDAF_assimilate_pf.F90', + 'PDAF/src/PDAF_assimilate_prepost.F90', + 'PDAF/src/PDAF_assimilate_seik.F90', + 'PDAF/src/PDAF_assim_interfaces.F90', + 'PDAF/src/PDAF_cb_procedures.F90', + 'PDAF/src/PDAF_comm_obs.F90', + 'PDAF/src/PDAF_communicate_ens.F90', + 'PDAF/src/PDAF_da.F90', + 'PDAF/src/PDAF_diag.F90', + 'PDAF/src/PDAF_en3dvar_analysis_cvt.F90', + 'PDAF/src/PDAF_en3dvar_optim.F90', + 'PDAF/src/PDAF_en3dvar_update.F90', + 'PDAF/src/PDAF_enkf_analysis_rlm.F90', + 'PDAF/src/PDAF_enkf_analysis_rsm.F90', + 'PDAF/src/PDAF_enkf.F90', + 'PDAF/src/PDAF_enkf_update.F90', + 'PDAF/src/PDAF_ensrf_analysis.F90', + 'PDAF/src/PDAF_ensrf.F90', + 'PDAF/src/PDAF_ensrf_update.F90', + 'PDAF/src/PDAF_estkf_analysis.F90', + 'PDAF/src/PDAF_estkf_analysis_fixed.F90', + 'PDAF/src/PDAF_estkf.F90', + 'PDAF/src/PDAF_estkf_update.F90', + 'PDAF/src/PDAF_etkf_analysis.F90', + 'PDAF/src/PDAF_etkf_analysis_fixed.F90', + 'PDAF/src/PDAF_etkf_analysis_T.F90', + 'PDAF/src/PDAF_etkf.F90', + 'PDAF/src/PDAF_etkf_update.F90', + 'PDAF/src/PDAF.F90', + 'PDAF/src/PDAF_forecast.F90', + 'PDAF/src/PDAF_generate_obs.F90', + 'PDAF/src/PDAF_generate_obs_update.F90', + 'PDAF/src/PDAF_genobs.F90', + 'PDAF/src/PDAF_get.F90', + 'PDAF/src/PDAF_get_state.F90', + 'PDAF/src/PDAF_hyb3dvar_analysis_cvt.F90', + 'PDAF/src/PDAF_hyb3dvar_optim.F90', + 'PDAF/src/PDAF_hyb3dvar_update.F90', + 'PDAF/src/PDAF_iau.F90', + 'PDAF/src/PDAF_info.F90', + 'PDAF/src/PDAF_init.F90', + 'PDAF/src/PDAF_lenkf_analysis_rsm.F90', + 'PDAF/src/PDAF_lenkf.F90', + 'PDAF/src/PDAF_lenkf_update.F90', + 'PDAF/src/PDAF_lestkf_analysis.F90', + 'PDAF/src/PDAF_lestkf_analysis_fixed.F90', + 'PDAF/src/PDAF_lestkf.F90', + 'PDAF/src/PDAF_lestkf_update.F90', + 'PDAF/src/PDAF_letkf_analysis.F90', + 'PDAF/src/PDAF_letkf_analysis_fixed.F90', + 'PDAF/src/PDAF_letkf_analysis_T.F90', + 'PDAF/src/PDAF_letkf.F90', + 'PDAF/src/PDAF_letkf_update.F90', + 'PDAF/src/PDAF_lknetf_analysis_step.F90', + 'PDAF/src/PDAF_lknetf_analysis_sync.F90', + 'PDAF/src/PDAF_lknetf.F90', + 'PDAF/src/PDAF_lknetf_update_step.F90', + 'PDAF/src/PDAF_lknetf_update_sync.F90', + 'PDAF/src/PDAF_lnetf_analysis.F90', + 'PDAF/src/PDAF_lnetf.F90', + 'PDAF/src/PDAF_lnetf_update.F90', + 'PDAF/src/PDAFlocal_assimilate_3dvars.F90', + 'PDAF/src/PDAFlocal_assimilate_ens.F90', + 'PDAF/src/PDAFlocal_callback.F90', + 'PDAF/src/PDAFlocal.F90', + 'PDAF/src/PDAFlocalomi_assimilate_3dvars.F90', + 'PDAF/src/PDAFlocalomi_assimilate_ens.F90', + 'PDAF/src/PDAFlocalomi_put_state_3dvars.F90', + 'PDAF/src/PDAFlocalomi_put_state_ens.F90', + 'PDAF/src/PDAFlocal_put_state_3dvars.F90', + 'PDAF/src/PDAFlocal_put_state_ens.F90', + 'PDAF/src/PDAF_lseik_analysis.F90', + 'PDAF/src/PDAF_lseik_analysis_trans.F90', + 'PDAF/src/PDAF_lseik.F90', + 'PDAF/src/PDAF_lseik_update.F90', + 'PDAF/src/PDAF_memcount.F90', + 'PDAF/src/PDAF_mod_core.F90', + 'PDAF/src/PDAF_mod_parallel.F90', + 'PDAF/src/PDAF_netf_analysis.F90', + 'PDAF/src/PDAF_netf.F90', + 'PDAF/src/PDAF_netf_update.F90', + 'PDAF/src/PDAFobs.F90', + 'PDAF/src/PDAFomi_assimilate_3dvars.F90', + 'PDAF/src/PDAFomi_assimilate_ens.F90', + 'PDAF/src/PDAFomi_assimilate_ens_nondiagR.F90', + 'PDAF/src/PDAFomi_callback.F90', + 'PDAF/src/PDAFomi_dim_obs_l.F90', + 'PDAF/src/PDAFomi.F90', + 'PDAF/src/PDAFomi_obs_diag.F90', + 'PDAF/src/PDAFomi_obs_f.F90', + 'PDAF/src/PDAFomi_obs_l.F90', + 'PDAF/src/PDAFomi_obs_op.F90', + 'PDAF/src/PDAFomi_put_state_3dvars.F90', + 'PDAF/src/PDAFomi_put_state_ens.F90', + 'PDAF/src/PDAFomi_put_state_ens_nondiagR.F90', + 'PDAF/src/PDAF_pf_analysis.F90', + 'PDAF/src/PDAF_pf.F90', + 'PDAF/src/PDAF_pf_update.F90', + 'PDAF/src/PDAF_prepost.F90', + 'PDAF/src/PDAF_put_state_3dvar.F90', + 'PDAF/src/PDAF_put_state_en3dvar_estkf.F90', + 'PDAF/src/PDAF_put_state_en3dvar_lestkf.F90', + 'PDAF/src/PDAF_put_state_enkf.F90', + 'PDAF/src/PDAF_put_state_ensrf.F90', + 'PDAF/src/PDAF_put_state_estkf.F90', + 'PDAF/src/PDAF_put_state_etkf.F90', + 'PDAF/src/PDAF_put_state_generate_obs.F90', + 'PDAF/src/PDAF_put_state_hyb3dvar_estkf.F90', + 'PDAF/src/PDAF_put_state_hyb3dvar_lestkf.F90', + 'PDAF/src/PDAF_put_state_lenkf.F90', + 'PDAF/src/PDAF_put_state_lestkf.F90', + 'PDAF/src/PDAF_put_state_letkf.F90', + 'PDAF/src/PDAF_put_state_lknetf.F90', + 'PDAF/src/PDAF_put_state_lnetf.F90', + 'PDAF/src/PDAF_put_state_lseik.F90', + 'PDAF/src/PDAF_put_state_netf.F90', + 'PDAF/src/PDAF_put_state_pf.F90', + 'PDAF/src/PDAF_put_state_prepost.F90', + 'PDAF/src/PDAF_put_state_seik.F90', + 'PDAF/src/PDAF_sample.F90', + 'PDAF/src/PDAF_seik_analysis.F90', + 'PDAF/src/PDAF_seik_analysis_newT.F90', + 'PDAF/src/PDAF_seik_analysis_trans.F90', + 'PDAF/src/PDAF_seik.F90', + 'PDAF/src/PDAF_seik_update.F90', + 'PDAF/src/PDAF_set.F90', + 'PDAF/src/PDAF_smoother.F90', + # 'PDAF/src/PDAF_timer.F90', + 'PDAF/src/PDAF_timer_mpi.F90', + 'PDAF/src/PDAF_utils.F90', + 'PDAF/src/PDAF_utils_filters.F90', + 'PDAF/external/SANGOMA/SANGOMA_quicksort.F90' + ) +pdaf_ext_sources = files('PDAF/external/CG+/cgfam.f', + 'PDAF/external/CG+/cgsearch.f', + 'PDAF/external/CG+_mpi/cgfam.f', + 'PDAF/external/CG+_mpi/cgsearch.f', + 'PDAF/external/LBFGS/lbfgsb.f', + 'PDAF/external/LBFGS/linpack.f', + 'PDAF/external/LBFGS/timer.f' + ) + +pdafc_sources = files('src/fortran/pdaf3_c_assim.f90', + 'src/fortran/pdaf3_c_put.f90', + 'src/fortran/pdaf3_c.f90', + 'src/fortran/pdaf_c_assim.f90', + 'src/fortran/pdaf_c_callback.f90', + 'src/fortran/pdaf_c_cb_interface.f90', + 'src/fortran/pdaf_c_diag.f90', + 'src/fortran/pdaf_c.f90', + 'src/fortran/pdaf_c_get.f90', + 'src/fortran/pdaf_c_iau.f90', + 'src/fortran/pdaf_c_iau_internal.f90', + 'src/fortran/pdaf_c_internal.f90', + 'src/fortran/pdaf_c_put.f90', + 'src/fortran/pdaf_c_setter.f90', + 'src/fortran/pdaflocal_c_assim.f90', + 'src/fortran/pdaflocal_c.f90', + 'src/fortran/pdaflocal_c_put.f90', + 'src/fortran/pdaflocalomi_c_assim.f90', + 'src/fortran/pdaflocalomi_c_put.f90', + 'src/fortran/pdafomi_c_assim.f90', + 'src/fortran/pdafomi_c_diag.f90', + 'src/fortran/pdafomi_c.f90', + 'src/fortran/pdafomi_c_internal.f90', + 'src/fortran/pdafomi_c_legacy.f90', + 'src/fortran/pdafomi_c_put.f90', + 'src/fortran/pdafomi_c_setter.f90', + 'src/fortran/pdaf_c_f_interface.f90' + ) + +if host_machine.system() == 'windows' + pdaf_ext_sources += files(mpimod) +endif + + +pdaf_ext = static_library( + 'pdaf_ext', + pdaf_ext_sources, + dependencies : [mpi, blas_dep], + fortran_args: fortran_ext_args, + link_language: 'fortran' +) + +pdafc_lib = shared_library( + 'PDAFc', + pdafc_sources + fortran_sources, + dependencies : [mpi, blas_dep], + fortran_args: fortran_args, + link_language: 'fortran', + link_whole: [pdaf_ext], + install_dir: python.get_install_dir() / 'pyPDAF', + vs_module_defs: 'pdaf_exports.def', + install: true +) + +cython_ext = python.extension_module( + 'pdaf_c_cb_interface', + 'src/pyPDAF/pdaf_c_cb_interface.pyx', + link_with: [pdafc_lib], + dependencies : [mpi, dep_py, blas_dep, fruntime_dep], + include_directories: include_directories([incdir_numpy]), + c_args: c_cython_args, + fortran_args: fortran_args, + cython_args : cython_args, + link_language: 'fortran', + subdir: 'pyPDAF', + install: true +) + +subdir('src/pyPDAF/PDAF') +subdir('src/pyPDAF/PDAF3') +subdir('src/pyPDAF/PDAFlocal') +subdir('src/pyPDAF/PDAFlocalomi') +subdir('src/pyPDAF/PDAFomi') + +python.install_sources(['src/pyPDAF/__init__.py', 'src/pyPDAF/py.typed'], subdir: 'pyPDAF') diff --git a/pyPDAF/source/meson.options b/pyPDAF/source/meson.options new file mode 100644 index 0000000000000000000000000000000000000000..46383e70e4e783f72dd9b70a36468468c7831261 --- /dev/null +++ b/pyPDAF/source/meson.options @@ -0,0 +1,4 @@ +option('incdirs', type : 'array', value : ['/usr/include'], description : 'Include directories for BLAS') +option('libdirs', type : 'array', value : ['/usr/lib'], description : 'Library directories for BLAS and other runtime libraries') +option('blas_lib', type : 'array', value : ['blas', 'lapack'], description : 'BLAS library name') +option('mpi_mod', type : 'string', value : '/usr/include/msmpi.f90', description : 'Path to mpi.f90 for MSMPI only') diff --git a/pyPDAF/source/pdaf_exports.def b/pyPDAF/source/pdaf_exports.def new file mode 100644 index 0000000000000000000000000000000000000000..dd3adb6f3f279f5cbae9ffd5a0b3103b7739a3e2 --- /dev/null +++ b/pyPDAF/source/pdaf_exports.def @@ -0,0 +1,642 @@ +LIBRARY PDAFc +EXPORTS + c__pdaf3_put_state_local_nondiagr + c__pdafomi_assimilate_lknetf_nondiagr + c__pdaf_3dvar_optim_cgplus + c__pdaf_smoother_lnetf + c__pdaf_assim_offline_lknetf + c__pdaf_local_weights + c__pdafomi_init_obsvar_l + c__pdafomi_generate_obs + c__pdaf_assimilate_hyb3dvar_estkf + c__pdafomi_put_state_local_nondiagr + c__pdaflocal_set_increment_weights + c__pdaf_diag_ensstats + c__pdafomi_diag_nobstypes + c__pdafhyb3dvar_analysis_cvt + c__pdafestkf_update + c__pdaf3_assim_offline_enkf_nondiagr + c__pdafomi_dealloc + c__pdafomi_init_dim_obs_l_noniso_old + c__pdaf_set_seedset + c__pdaf3_put_state_en3dvar + c__pdafomi_put_state_lknetf_nondiagr + c__pdafomi_set_globalobs + c__pdaf_lenkf_config + c__pdaflocalomi_assimilate_nondiagr + c__pdaf_iau_init + c__pdaf_lenkf_set_rparam + c__pdafomi_put_state_hyb3dvar_estkf_nondiagr + c__pdaf3_assim_offline_3dvar_all + c__pdafomi_set_domainsize + c__pdafomi_check_dist2 + c__pdafen3dvar_update_estkf + c__pdafhyb3dvar_update_lestkf + c__pdafomi_obs_op_adj_gridavg + c__pdaf_netf_set_iparam + c__pdaf_print_version + c__pdaf_etkf_set_rparam + c__pdaf3_assimilate_global + c__pdafomi_prodrinva_l + c__pdaf_pf_config + c__pdafomi_set_obs_diag + c__pdaf_lestkf_config + c__pdaf_assimilate_3dvar + c__pdafomi_diag_stats + c__pdaf3_assim_offline_hyb3dvar_estkf + c__pdafomi_assimilate_nonlin_nondiagr + c__pdaf_en3dvar_optim_lbfgs + c__pdaf_lseik_set_rparam + c__pdaf_add_particle_noise + c__pdaf_diag_stddev_nompi + c__pdafomi_omit_by_inno_l + c__pdaf3dvar_update + c__pdaf_hyb3dvar_optim_cg + c__pdaf_set_rparam_filters + c__pdafomi_put_state_lnetf_nondiagr + c__pdafomi_set_localization_noniso + c__pdaf_seik_options + c__pdafomi_likelihood_cb + c__pdaflocalomi_assimilate_lnetf_nondiagr + c__pdaflocal_g2l_cb + c__pdafomi_diag_get_obs + c__pdaf_init_forecast + c__pdaf_smoother_netf + c__pdafomi_localize_covar_serial_cb + c__pdaf_estkf_memtime + c__pdafomi_assimilate_lnetf_nondiagr + c__pdafomi_limit_obs_f + c__pdaf_ensrf_init + c__pdaf3_put_state_global + c__pdaf_enkf_memtime + c__pdaf_set_smootherens + c__pdaf_seik_set_rparam + c__pdaf_diag_variance + c__pdaf_lenkf_init + c__pdaf_3dvar_costf_cg_cvt + c__pdaf_smoothing + c__pdafomi_put_state_en3dvar_lestkf + c__pdaf_enkf_ana_rsm + c__pdafomi_put_state_3dvar_nondiagr + c__pdaf_lseik_options + c__pdafnetf_update + c__pdaf_assimilate_lenkf + c__pdaf_assim_offline_3dvar + c__pdaf_diag_ensmean + c__pdaf_gather_obs_f + c__pdaf_estkf_alloc + c__pdaf_iau_init_weights + c__pdafomi_store_obs_l_index + c__pdaf_subtract_rowmean + c__pdaf_put_state_etkf + c__pdafomi_prodrinva_cb + c__pdaf_eofcovar + c__pdaf_3dvar_alloc + c__pdaf_lnetf_init + c__pdaf_lnetf_alloc + c__pdafomi_assimilate_lenkf_nondiagr + c__pdafomi_init_obscovar_cb + c__pdaf3_assim_offline_local_nondiagr + c__pdaf_etkf_set_iparam + c__pdafomi_set_localization + c__pdaf_ensrf_memtime + c__pdaf_3dvar_set_rparam + c__pdaf_init_local_obsstats + c__pdaf_lknetf_analysis_t + c__pdaf_diag_rmsd_nompi + c__pdaf_seik_ttimesa + c__pdaf_fcst_operations + c__pdafomi_set_localize_covar_noniso + c__pdaf_en3dvar_costf_cvt + c__pdafomi_set_localize_covar_iso + c__pdafomi_init_obs_f + c__pdaf_assim_offline_etkf + c__pdaf_lenkf_alloc + c__pdafomi_init_obs_l_cb + c__pdaf_genobs_config + c__pdaf_lenkf_memtime + c__pdaf_netf_init + c__pdaf_set_ens_pointer + c__pdaf3_assim_offline_ensrf + c__pdafomi_init_obs_f_cb + c__pdaf_pf_set_rparam + c__pdaf_lestkf_set_iparam + c__pdaf_letkf_memtime + c__pdafomi_set_inno_omit + c__pdaf_put_state_hyb3dvar_lestkf + c__pdaf3_assimilate_lenkf + c__pdafomi_get_interp_coeff_tri + c__pdafpf_update + c__pdafomi_localize_covar_noniso_locweights + c__pdaf3_put_state_lnetf_nondiagr + c__pdaf_iau_init_inc + c__pdafomi_assimilate_global + c__pdaf_gather_ens + c__pdaf3_assim_offline_en3dvar_estkf_nondiagr + c__pdaf_enkf_alloc + c__pdaf_put_state_ensrf + c__pdaf_put_state_estkf + c__pdaf3_assimilate_hyb3dvar + c__pdaf_enkf_set_iparam + c__pdafomi_prodrinva_hyb_l + c__pdaf3_put_state_enkf_nondiagr + c__pdaf3_assim_offline_3dvar + c__pdafomi_set_localize_covar_noniso_locweights + c__pdafomi_assimilate_hyb3dvar_estkf_nondiagr + c__pdaf_assim_offline_enkf + c__pdafomi_local_weight + c__pdaf_allreduce + c__pdaf3_assim_offline_global_nondiagr + c__pdaf_lknetf_alloc + c__pdafomi_omit_by_inno_cb + c__pdaf_lseik_memtime + c__pdaf_lseik_resample + c__pdafomi_likelihood_hyb_l + c__pdaflocal_put_state_lnetf + c__pdaf_lnetf_smoothert + c__pdafomi_set_doassim + c__pdafobs_init_obsvars + c__pdaflocal_clear_increment_weights + c__pdaf_lknetf_alpha_neff + c__pdaf_3dvar_optim_cg + c__pdaf_put_state_en3dvar_estkf + c__pdaf3_assimilate_en3dvar + c__pdaf3_assimilate_en3dvar_estkf + c__pdaflknetf_update_step + c__pdafomi_localize_covar_noniso + c__pdaf_memcount_define + c__pdaf_mvnormalize + c__pdafomi_weights_l_sgnl + c__pdaf_lenkf_options + c__pdafomi_assimilate_en3dvar_estkf + c__pdaf_en3dvar_costf_cg_cvt + c__pdaf_estkf_init + c__pdaf_put_state_lestkf + c__pdafomi_cnt_dim_obs_l + c__pdafomi_init_dim_obs_l_noniso_locweights_old + c__pdaf_etkf_options + c__pdaf3_assimilate_lnetf_nondiagr + c__pdafomi_put_state_generate_obs + c__pdaflocal_assimilate_lestkf + c__pdaflocal_put_state_hyb3dvar_lestkf + c__pdaf3_assimilate_local + c__pdaf_lseik_ana + c__pdaf_estkf_omegaa + c__pdaf_lnetf_ana + c__pdafomi_diag_omit_by_inno + c__pdaf3_put_state_ensrf + c__pdaf_seik_uinv + c__pdaf_print_da_types + c__pdaf_iau_update_inc + c__pdaf3_assim_offline_en3dvar_estkf + c__pdaf_lnetf_memtime + c__pdafomi_get_domain_limits_unstr + c__pdaf_pf_resampling + c__pdafomi_init_obscovar + c__pdafensrf_update + c__pdaf_lestkf_init + c__pdafomi_likelihood_hyb_l_cb + c__pdaflocalomi_assimilate_en3dvar_lestkf_nondiagr + c__pdafomi_g2l_obs_internal + c__pdaf_print_domain_stats + c__pdaf_generate_rndmat + c__pdafobs_init_local + c__pdaf_assimilate_netf + c__pdaf_generate_obs_offline + c__pdaf_en3dvar_optim_cg + c__pdaf_lestkf_set_rparam + c__pdaf3_generate_obs + c__pdaf3_put_state_3dvar_nondiagr + c__pdaf_iau_update_ens + c__pdaf_gather_dim_obs_f + c__pdaf_put_state_seik + c__pdaf_get_state + c__pdaf3_assimilate_local_nondiagr + c__pdaf_lknetf_reset_gamma + c__pdaf_seik_resample_newt + c__pdaf_scatter_ens + c__pdaf_print_filter_types + c__pdaf_put_state_netf + c__pdafomi_localize_covar_serial_noniso_locweights + c__pdaf_pf_set_iparam + c__pdaf_force_analysis + c__pdaf_seik_init + c__pdaf_sampleens + c__pdaf_3dvar_costf_cvt + c__pdafomi_put_state_nonlin_nondiagr + c__pdaf_seik_alloc + c__pdaf_hyb3dvar_optim_lbfgs + c__pdaf_assimilate_pf + c__pdaf_assim_offline_lenkf + c__pdafomi_put_state_hyb3dvar_lestkf_nondiagr + c__pdafomi_localize_covar_iso + c__pdaf3_put_state_lenkf + c__pdaflocal_assimilate_lknetf + c__pdafomi_likelihood_l_cb + c__pdaf3_assim_offline_hyb3dvar_estkf_nondiagr + c__pdaf_enkf_config + c__pdaf_get_ensstats + c__pdaf_set_forget_local + c__pdaf_assimilate_estkf + c__pdafomi_put_state_global + c__pdaf_correlation_function + c__pdafomi_init_obsarrays_l_noniso + c__pdaf_set_offline_mode + c__pdaf_seik_omega + c__pdafomi_get_interp_coeff_lin + c__pdaf3_assim_offline_3dvar_nondiagr + c__pdaf3_put_state_en3dvar_estkf + c__pdaf_assimilate_lseik + c__pdaf_get_smootherens + c__pdaflocalomi_assimilate_lknetf_nondiagr + c__pdaf_set_iparam_filters + c__pdaf_pf_init + c__pdafomi_put_state_global_nondiagr + c__pdaf_lenkf_set_iparam + c__pdaf_smoother_shift + c__pdafomi_weights_l + c__pdafhyb3dvar_update_estkf + c__pdaf_hyb3dvar_optim_cgplus + c__pdaf_genobs_set_iparam + c__pdafomi_init + c__pdafomi_init_dim_obs_l_noniso + c__pdaf_assimilate_lestkf + c__pdaflestkf_update + c__pdaf_lnetf_set_rparam + c__pdaf_put_state_en3dvar_lestkf + c__pdaf3_put_state_3dvar + c__pdaf_put_state_lnetf + c__pdafomi_init_obsvars_f + c__pdaf3_assimilate_en3dvar_lestkf_nondiagr + c__pdaf_etkf_alloc + c__pdafomi_obsstats_l + c__pdafomi_likelihood + c__pdaf_3dvar_optim_lbfgs + c__pdafomi_assimilate_local_nondiagr + c__pdaf_iau_set_weights + c__pdaf_lknetf_memtime + c__pdaflocal_put_state_letkf + c__pdaf_ensrf_ana_2step + c__pdaf_iau_add_inc + c__pdafomi_init_obserr_f_cb + c__pdaf_gather_obs_f_flex + c__pdaf_lseik_ana_trans + c__pdaf3dvar_analysis_cvt + c__pdaf_lnetf_options + c__pdaf_etkf_ana + c__pdaf_hyb3dvar_costf_cvt + c__pdaf_put_state_hyb3dvar_estkf + c__pdaf3_assimilate_3dvar_nondiagr + c__pdaf_gather_obs_f2_flex + c__pdafomi_comp_dist2 + c__pdafomi_obsstats + c__pdafomi_assimilate_en3dvar_estkf_nondiagr + c__pdaf3_put_state_hyb3dvar_estkf + c__pdaf3_put_state_en3dvar_lestkf_nondiagr + c__pdafomi_init_obsvar_f + c__pdaf3_put_state_hyb3dvar_lestkf + c__pdafomi_check_dist2_noniso + c__pdaf_generate_obs + c__pdafomi_put_state_local + c__pdafomi_set_domain_limits + c__pdafomi_set_inno_omit_ivar + c__pdaf_print_info_filters + c__pdaf3_put_state_hyb3dvar + c__pdaf3_assim_offline_en3dvar + c__pdaf_3dvar_memtime + c__pdaf3_assim_offline_global + c__pdafomi_diag_get_hx + c__pdaf3_assim_offline_lenkf_nondiagr + c__pdaf_letkf_ana + c__pdaf_put_state_enkf + c__pdaf_lknetf_ana_lnetf + c__pdaf_3dvar_init + c__pdafomi_store_obs_l_index_vdist + c__pdaf_lestkf_ana_fixed + c__pdaflocalomi_put_state_hyb3dvar_lestkf_nondiagr + c__pdaflenkf_update + c__pdaf_letkf_set_rparam + c__pdaf_put_state_generate_obs + c__pdafomi_set_ncoord + c__pdaf_assim_offline_en3dvar_lestkf + c__pdaf_diag_compute_moments + c__pdaf_estkf_ana_fixed + c__pdaf_alloc + c__pdafomi_init_obsvars_f_cb + c__pdaf_netf_smoothert + c__pdafomi_prodrinva_l_cb + c__pdaf_lestkf_options + c__pdaf_assim_offline_pf + c__pdaflnetf_update + c__pdaflocal_assimilate_en3dvar_lestkf + c__pdaf_set_debug_flag + c__pdafomi_gather_obs + c__pdafomi_init_dim_obs_l_noniso_locweights + c__pdafomi_prodrinva + c__pdaf_pf_options + c__pdafomi_diag_get_hxmean + c__pdaflocal_put_state_lknetf + c__pdaf_genobs_options + c__pdaf3_put_state_hyb3dvar_estkf_nondiagr + c__pdaf3_assimilate_en3dvar_estkf_nondiagr + c__pdaf_enkf_set_rparam + c__pdafomi_init_obserr_f + c__pdaf3_put_state + c__pdaf_genobs_init + c__pdaf3_put_state_3dvar_all + c__pdaf_prepost + c__pdaflocalomi_put_state_en3dvar_lestkf + c__pdaf_letkf_init + c__pdafomi_check_error + c__pdaf_lknetf_set_rparam + c__pdafenkf_update + c__pdaf_assim_offline_letkf + c__pdafomi_assimilate_3dvar_nondiagr + c__pdafomi_obs_op_interp_lin + c__pdaf_seik_memtime + c__pdaf_seik_resample + c__pdaf_assimilate_en3dvar_estkf + c__pdafobs_init + c__pdaf_lestkf_alloc + c__pdafetkf_update + c__pdaf3_assim_offline_hyb3dvar_lestkf + c__pdaf_assimilate_enkf + c__pdaf_estkf_aomega + c__pdaf_etkf_memtime + c__pdafomi_init_dim_obs_l_iso + c__pdaf_put_state_lseik + c__pdafomi_init_dim_obs_l_iso_old + c__pdafomi_set_obs_err_type + c__pdaf3_assim_offline + c__pdaf_lenkf_ana_rsm + c__pdaf_assim_offline_estkf + c__pdaf_reset_dim_ens + c__pdaf_seik_ana_newt + c__pdaf_lknetf_set_iparam + c__pdaf_reset_dim_p + c__pdaf3_assim_offline_lenkf + c__pdafomi_set_use_global_obs + c__pdafomi_put_state_3dvar + c__pdaf3_assimilate_ensrf + c__pdaf_incr_local_obsstats + c__pdaf_put_state_lenkf + c__pdafomi_omit_by_inno + c__pdaf_netf_options + c__pdafomi_prodrinva_hyb_l_cb + c__pdafomi_obs_op_gatheronly + c__pdaf_assimilate_lnetf + c__pdaf_netf_config + c__pdaf_inflate_ens + c__pdaf_etkf_ana_t + c__pdaf_assimilate_ensrf + c__pdaf_assim_offline_seik + c__pdafen3dvar_analysis_cvt + c__pdafobs_dealloc_local + c__pdaf_lknetf_options + c__pdaf_letkf_set_iparam + c__pdaflocalomi_put_state + c__pdaf_assim_offline_ensrf + c__pdaf_netf_ana + c__pdaf3_put_state_lknetf_nondiagr + c__pdafomi_assimilate_en3dvar_lestkf_nondiagr + c__pdaf3_put_state_hyb3dvar_lestkf_nondiagr + c__pdaf_diag_reliability_budget + c__pdaf_get_localfilter + c__pdafomi_init_obsarrays_l + c__pdaf_set_forget + c__pdaf_get_fcst_info + c__pdaf_get_obsmemberid + c__pdafomi_obs_op_adj_interp_lin + c__pdafomi_g2l_obs + c__pdaf_ensrf_options + c__pdaf_gather_obs_f2 + c__pdafseik_update + c__pdaf_enkf_options + c__pdaf_diag_stddev + c__pdafomi_diag_dimobs + c__pdafobs_dealloc + c__pdaf_assimilate_etkf + c__pdafomi_init_local + c__pdaf_diag_crps_nompi + c__pdaf_diag_crps_mpi + c__pdafomi_put_state_lenkf_nondiagr + c__pdaflocal_assimilate_lnetf + c__pdafomi_observation_localization_weights + c__pdafomi_init_obsvar_cb + c__pdaf_lestkf_memtime + c__pdaf_netf_set_rparam + c__pdaflknetf_update_sync + c__pdafomi_check_dist2_loop + c__pdaf_assim_offline_hyb3dvar_estkf + c__pdafomi_assimilate_global_nondiagr + c__pdaf_hyb3dvar_costf_cg_cvt + c__pdafomi_deallocate_obs + c__pdafomi_assimilate_ensrf + c__pdafomi_put_state_hyb3dvar_lestkf + c__pdaf_set_comm_pdaf + c__pdaf_assimilate_lknetf + c__pdafomi_obs_op_gridavg + c__pdaf3_assimilate_hyb3dvar_estkf + c__pdaf_iau_reset + c__pdaf_pf_ana + c__pdaf_local_weight + c__pdaf_memcount_ini + c__pdaf_alloc_filters + c__pdafomi_ocoord_all + c__pdaf3_put_state_en3dvar_lestkf + c__pdaf_sisort + c__pdaf_smoothing_local + c__pdaf_ensrf_ana + c__pdaf_estkf_config + c__pdaf_put_state_letkf + c__pdaf_deallocate + c__pdaf_enkf_init + c__pdaf_en3dvar_optim_cgplus + c__pdaflocalomi_assimilate + c__pdaf_assim_offline_lestkf + c__pdaf_set_memberid + c__pdafomi_diag_obs_rmsd + c__pdaf_get_memberid + c__pdafomi_assimilate_lenkf + c__pdaf_assimilate_seik + c__pdaf_put_state_prepost + c__pdaf3_put_state_nonlin_nondiagr + c__pdaf3_put_state_en3dvar_estkf_nondiagr + c__pdafomi_obs_op_adj_gridpoint + c__pdaf3_put_state_lenkf_nondiagr + c__pdaf_init + c__pdafomi_assimilate_hyb3dvar_lestkf_nondiagr + c__pdaf_diag_histogram + c__pdaf_lnetf_config + c__pdafomi_assimilate_hyb3dvar_estkf + c__pdaf_lseik_set_iparam + c__pdaflocalomi_assimilate_hyb3dvar_lestkf + c__pdaflocal_put_state_lseik + c__pdafomi_localize_covar_cb + c__pdafomi_set_dim_obs_l + c__pdaf_assim_offline_lnetf + c__pdaf_lseik_config + c__pdaf_netf_alloc + c__pdaf_lknetf_config + c__pdaflocalomi_put_state_lknetf_nondiagr + c__pdafomi_put_state_ensrf + c__pdaf_lknetf_ana_letkft + c__pdaf_put_state_3dvar + c__pdaf_diag_effsample + c__pdaf_seik_config + c__pdaf_set_rparam + c__pdaf_print_local_obsstats + c__pdafomi_put_state_lenkf + c__pdafomi_set_debug_flag + c__pdaflocalomi_assimilate_en3dvar_lestkf + c__pdaf_ens_omega + c__pdaf_letkf_options + c__pdaf_letkf_ana_fixed + c__pdaf_configinfo_filters + c__pdafomi_likelihood_l + c__pdafomi_put_state_en3dvar_lestkf_nondiagr + c__pdaf_seik_ana_trans + c__pdafomi_set_icoeff_p + c__pdaflocal_assimilate_lseik + c__pdaf_seik_ana + c__pdaf3_assim_offline_en3dvar_lestkf + c__pdaflocalomi_assimilate_hyb3dvar_lestkf_nondiagr + c__pdafomi_put_state_en3dvar_estkf + c__pdaf_memcount + c__pdaf_init_parallel + c__pdaf_etkf_ana_fixed + c__pdaf3_assimilate + c__pdaf_lseik_init + c__pdaf_ensrf_set_iparam + c__pdaf_enkf_gather_resid + c__pdaf_gen_obs + c__pdafomi_assimilate_hyb3dvar_lestkf + c__pdaf_3dvar_config + c__pdaf_pf_memtime + c__pdaf_ensrf_config + c__pdaf_letkf_config + c__pdaf_ensrf_alloc + c__pdaf3_assimilate_lknetf_nondiagr + c__pdafomi_init_obsvar_l_cb + c__pdaf_letkf_alloc + c__pdafomi_diag_get_ivar + c__pdaflocal_put_state_lestkf + c__pdaflocalomi_put_state_hyb3dvar_lestkf + c__pdafomi_g2l_obs_cb + c__pdaf3_assim_offline_local + c__pdaf3_assimilate_en3dvar_lestkf + c__pdaf_diag_rmsd + c__pdafomi_localize_covar_serial_iso + c__pdaf_put_state_pf + c__pdafomi_assimilate_local + c__pdaf3_assim_offline_lnetf_nondiagr + c__pdaf_lknetf_set_gamma + c__pdaf3_put_state_generate_obs + c__pdafomi_gather_obsdims + c__pdaf_ensrf_set_rparam + c__pdaf_iau_set_pointer + c__pdafomi_get_interp_coeff_lin1d + c__pdaf_smoother_enkf + c__pdaf_3dvar_options + c__pdaf_seik_set_iparam + c__pdaf3_assim_offline_hyb3dvar_lestkf_nondiagr + c__pdaf_put_state_lknetf + c__pdaf_assim_offline_netf + c__pdafomi_put_state_en3dvar_estkf_nondiagr + c__pdafomi_set_id_obs_p + c__pdaf_3dvar_set_iparam + c__pdaf_netf_memtime + c__pdaf_iau_add_inc_ens + c__pdaf_iau_dealloc + c__pdaf3_assimilate_lenkf_nondiagr + c__pdaf3_assimilate_nonlin_nondiagr + c__pdaf_genobs_alloc + c__pdafomi_add_obs_error + c__pdaf_lnetf_set_iparam + c__pdaf_options_filters + c__pdafomi_assimilate_enkf_nondiagr + c__pdaf_assim_offline_lseik + c__pdaf_get_assim_flag + c__pdaflocal_put_state_en3dvar_lestkf + c__pdaflocal_set_indices + c__pdaf3_assim_offline_hyb3dvar + c__pdaf_assim_offline_en3dvar_estkf + c__pdaf_set_iparam + c__pdaflocal_assimilate_hyb3dvar_lestkf + c__pdaf_assimilate_letkf + c__pdaf3_assimilate_enkf_nondiagr + c__pdaf_diag_variance_nompi + c__pdafomi_obs_op_gridpoint + c__pdaf_lseik_alloc + c__pdaf_print_info + c__pdaf_assimilate_prepost + c__pdaf_seik_matrixt + c__pdafomi_gather_obs_f_flex + c__pdaflocalomi_put_state_nondiagr + c__pdafomi_get_local_ids_obs_f + c__pdafomi_gather_obs_f2_flex + c__pdaf_enkf_ana_rlm + c__pdaf_inflate_weights + c__pdaf3_assim_offline_nonlin_nondiagr + c__pdafomi_assimilate_en3dvar_lestkf + c__pdaf_reset_forget + c__pdafomi_check_dist2_noniso_loop + c__pdaf_etkf_init + c__pdaf_subtract_colmean + c__pdaf3_generate_obs_offline + c__pdafomi_gather_obsstate + c__pdaf_etkf_config + c__pdaf3_assimilate_hyb3dvar_estkf_nondiagr + c__pdaf_enkf_obs_ensemble + c__pdaf_get_local_type + c__pdafomi_localize_covar_serial_noniso + c__pdafomi_gather_dim_obs_f + c__pdaflseik_update + c__pdafomi_put_state_hyb3dvar_estkf + c__pdaf3_assim_offline_en3dvar_lestkf_nondiagr + c__pdaf3_assimilate_hyb3dvar_lestkf_nondiagr + c__pdaf_estkf_set_rparam + c__pdaflocal_assimilate_letkf + c__pdaflocalomi_put_state_lnetf_nondiagr + c__pdafomi_obs_op_adj_gatheronly + c__pdafen3dvar_update_lestkf + c__pdaf_letkf_ana_t + c__pdaf3_assimilate_hyb3dvar_lestkf + c__pdaf_estkf_ana + c__pdaf_assim_offline_hyb3dvar_lestkf + c__pdaf_estkf_set_iparam + c__pdaflocal_l2g_cb + c__pdaf3_assimilate_global_nondiagr + c__pdaf_init_filters + c__pdafomi_cnt_dim_obs_l_noniso + c__pdaf_pf_alloc + c__pdafomi_omit_by_inno_l_cb + c__pdaf3_assim_offline_lknetf_nondiagr + c__pdafomi_set_disttype + c__pdaf3_assimilate_3dvar + c__pdafomi_assimilate_3dvar + c__pdafomi_init_obs_l + c__pdaf_lknetf_init + c__pdaf_assimilate_hyb3dvar_lestkf + c__pdaf3_put_state_global_nondiagr + c__pdafomi_add_obs_error_cb + c__pdaf_assimilate_en3dvar_lestkf + c__pdaf_lestkf_ana + c__pdaf3_put_state_local + c__pdaflocalomi_put_state_en3dvar_lestkf_nondiagr + c__pdafletkf_update + c__pdaf3_assimilate_3dvar_all + c__pdaf_lknetf_compute_gamma + c__pdaf_estkf_options + c__pdafomi_put_state_enkf_nondiagr + c__pdaf3_init + c__pdaf3_init_forecast + c__pdaf3_set_parallel + c__pdaf_iau_set_ens_pointer + c__pdaf_iau_set_state_pointer + c__pdafomi_obs_op_extern + c__pdafomi_set_name + c__pdaf_mpi_init + c__pdaf_timeit + c__pdaf_alloc_sens + c__pdaf_alloc_bias \ No newline at end of file diff --git a/pyPDAF/source/pyproject.toml b/pyPDAF/source/pyproject.toml new file mode 100644 index 0000000000000000000000000000000000000000..79d6253aca34136d563612ab135180eed84783f3 --- /dev/null +++ b/pyPDAF/source/pyproject.toml @@ -0,0 +1,18 @@ +[build-system] + requires = ["meson-python", "cython", "numpy"] + build-backend = "mesonpy" + +[project] +name = "pyPDAF" +authors = [ + {name = "Yumeng Chen", email = "yumeng.chen@reading.ac.uk"}, +] +version = "1.0.4" +description = "A Python interface to Parallel Data Assimilation Framework (PDAF)" +readme = "README.md" +requires-python = ">=3.10" +keywords = ["data assimilation", "PDAF"] +license = {text = "GPL License"} +dependencies = [ + "numpy", "mpi4py" +] \ No newline at end of file diff --git a/pyPDAF/source/src/__init__.py b/pyPDAF/source/src/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e6e237ed8dcb6e6cc47eed4854b52979143e6191 --- /dev/null +++ b/pyPDAF/source/src/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +""" +src Package Initialization File +""" diff --git a/pyPDAF/source/src/__pycache__/__init__.cpython-310.pyc b/pyPDAF/source/src/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..13621ee6c042fc86e17c9ab38dfb9b425b77de03 Binary files /dev/null and b/pyPDAF/source/src/__pycache__/__init__.cpython-310.pyc differ diff --git a/pyPDAF/source/src/fortran/pdaf3_c.f90 b/pyPDAF/source/src/fortran/pdaf3_c.f90 new file mode 100644 index 0000000000000000000000000000000000000000..912ba1e45191688c834623e55c3841bef1c15d86 --- /dev/null +++ b/pyPDAF/source/src/fortran/pdaf3_c.f90 @@ -0,0 +1,112 @@ +module pdaf3_c +use iso_c_binding, only: c_int, c_double, c_bool +use pdaf +implicit none + +contains + SUBROUTINE c__PDAF3_init(filtertype, subtype, stepnull, param_int, dim_pint, & + param_real, dim_preal, U_init_ens, in_screen, outflag) bind(c) + use pdaf_c_f_interface, only: init_ens_pdaf_c_ptr, & + f__init_ens_pdaf + use pdaf_c_cb_interface, only: c__init_ens_pdaf + IMPLICIT NONE + + ! *** Arguments *** + ! For valid and default values see PDAF_mod_core.F90 + !< Type of filter + INTEGER(c_int), INTENT(in) :: filtertype + !< Sub-type of filter + INTEGER(c_int), INTENT(in) :: subtype + !< Initial time step of assimilation + INTEGER(c_int), INTENT(in) :: stepnull + !< Number of integer parameters + INTEGER(c_int), INTENT(in) :: dim_pint + !< Integer parameter array + INTEGER(c_int), dimension(dim_pint), INTENT(inout) :: param_int + !< Number of real parameter + INTEGER(c_int), INTENT(in) :: dim_preal + !< Real parameter array + REAL(c_double), dimension(dim_preal), INTENT(inout) :: param_real + !< Control screen output: + !< (0) none, (1) some, default, (2) extensive + INTEGER(c_int), INTENT(in) :: in_screen + !< Status flag, 0: no error, error codes: + !< -1: Call with subtype=-1 for info display + !< 1: No valid filter type + !< 2: No valid sub type + !< 3: Invalid dim_pint + !< 4: Invalid dim_preal + !< 5: Invalid state dimension + !< 6: Invalid ensemble size + !< 7: Invalid value for forgetting factor + !< 8: Invalid other integer parameter value + !< 9: Invalid other real parameter value + !< 10: MPI information not initialized + !< 20: error in allocation of array at PDAF init + INTEGER(c_int), INTENT(out):: outflag + ! *** External subroutines *** + ! (PDAF-internal names, real names are defined in the call to PDAF) + ! User-supplied routine for ensemble initialization + procedure(c__init_ens_pdaf) :: u_init_ens + + init_ens_pdaf_c_ptr => u_init_ens + + call PDAF3_init(filtertype, subtype, stepnull, param_int, dim_pint, & + param_real, dim_preal, f__init_ens_pdaf, in_screen, outflag) + + END SUBROUTINE c__PDAF3_init + + SUBROUTINE c__PDAF3_init_forecast(U_next_observation, U_distribute_state, & + U_prepoststep, outflag) bind(c) + use pdaf_c_f_interface, only: next_observation_pdaf_c_ptr, & + f__next_observation_pdaf, & + distribute_state_pdaf_c_ptr, & + f__distribute_state_pdaf, & + prepoststep_pdaf_c_ptr, & + f__prepoststep_pdaf + use pdaf_c_cb_interface, only: c__next_observation_pdaf, & + c__distribute_state_pdaf, & + c__prepoststep_pdaf + implicit none + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: u_next_observation + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + next_observation_pdaf_c_ptr => u_next_observation + distribute_state_pdaf_c_ptr => u_distribute_state + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAF3_init_forecast(f__next_observation_pdaf, f__distribute_state_pdaf, & + f__prepoststep_pdaf, outflag) + END SUBROUTINE c__PDAF3_init_forecast + + SUBROUTINE c__PDAF3_set_parallel(in_COMM_pdaf, in_COMM_model, in_COMM_filter, in_COMM_couple, & + in_task_id, in_n_modeltasks, in_filterpe, flag) bind(c) + IMPLICIT NONE + !< MPI communicator for all PEs involved in PDAF + INTEGER(c_int), INTENT(in) :: in_COMM_pdaf + !< Model communicator + INTEGER(c_int), INTENT(in) :: in_COMM_model + !< Filter communicator + INTEGER(c_int), INTENT(in) :: in_COMM_filter + !< Coupling communicator + INTEGER(c_int), INTENT(in) :: in_COMM_couple + !< Task ID of current PE + INTEGER(c_int), INTENT(in) :: in_task_id + !< Number of model tasks + INTEGER(c_int), INTENT(in) :: in_n_modeltasks + !< Is my PE a filter-PE? + LOGICAL(c_bool), INTENT(in) :: in_filterpe + !< Status flag + INTEGER(c_int), INTENT(inout):: flag + + call PDAF3_set_parallel(in_COMM_pdaf, in_COMM_model, in_COMM_filter, in_COMM_couple, & + in_task_id, in_n_modeltasks, logical(in_filterpe), flag) + END SUBROUTINE c__PDAF3_set_parallel +end module pdaf3_c \ No newline at end of file diff --git a/pyPDAF/source/src/fortran/pdaf3_c_assim.f90 b/pyPDAF/source/src/fortran/pdaf3_c_assim.f90 new file mode 100644 index 0000000000000000000000000000000000000000..c02e8e5072d785bf4964b939e368ac6fe99abaec --- /dev/null +++ b/pyPDAF/source/src/fortran/pdaf3_c_assim.f90 @@ -0,0 +1,2254 @@ +MODULE pdaf3_c_assim +use iso_c_binding, only: c_double, c_int, c_bool +use PDAF +use pdaf_c_cb_interface +use pdaf_c_f_interface + +implicit none + +contains + SUBROUTINE c__PDAF3_assimilate_3dvar_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, prodrinva_pdaf, & + cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, & + prepoststep_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_3dvar_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, & + f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_3dvar_nondiagR + + SUBROUTINE c__PDAF3_assimilate_en3dvar_estkf_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, prodrinva_pdaf, & + cvt_ens_pdaf, cvt_adj_ens_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, & + prepoststep_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_en3dvar_estkf_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, & + f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_en3dvar_estkf_nondiagR + + SUBROUTINE c__PDAF3_assimilate_en3dvar_lestkf_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, prodrinva_pdaf, & + cvt_ens_pdaf, cvt_adj_ens_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, & + prodrinva_l_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, prepoststep_pdaf, next_observation_pdaf, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide product R^-1 A and apply localizations + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_en3dvar_lestkf_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, & + f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_en3dvar_lestkf_nondiagR + + SUBROUTINE c__PDAF3_assimilate_hyb3dvar_estkf_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, prodrinva_pdaf, & + cvt_ens_pdaf, cvt_adj_ens_pdaf, cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, & + obs_op_adj_pdaf, prepoststep_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_hyb3dvar_estkf_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, & + f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_hyb3dvar_estkf_nondiagR + + SUBROUTINE c__PDAF3_assimilate_hyb3dvar_lestkf_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, prodrinva_pdaf, & + cvt_ens_pdaf, cvt_adj_ens_pdaf, cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, & + obs_op_adj_pdaf, prodrinva_l_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, prepoststep_pdaf, next_observation_pdaf, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide product R^-1 A and apply localizations + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_hyb3dvar_lestkf_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, & + f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__prodrinva_l_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_hyb3dvar_lestkf_nondiagR + + SUBROUTINE c__PDAF3_assim_offline_3dvar_all(init_dim_obs_pdaf, obs_op_pdaf, & + cvt_ens_pdaf, cvt_adj_ens_pdaf, cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, & + obs_op_adj_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_3dvar_all(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_3dvar_all + + SUBROUTINE c__PDAF3_assim_offline_3dvar(init_dim_obs_pdaf, obs_op_pdaf, & + cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, & + prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_3dvar(f__init_dim_obs_pdaf, f__obs_op_pdaf, f__cvt_pdaf, & + f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_3dvar + + SUBROUTINE c__PDAF3_assim_offline_en3dvar(init_dim_obs_pdaf, obs_op_pdaf, & + cvt_ens_pdaf, cvt_adj_ens_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, & + init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdaf, & + prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_en3dvar(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_en3dvar + + SUBROUTINE c__PDAF3_assim_offline_en3dvar_estkf(init_dim_obs_pdaf, & + obs_op_pdaf, cvt_ens_pdaf, cvt_adj_ens_pdaf, obs_op_lin_pdaf, & + obs_op_adj_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_en3dvar_estkf(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_en3dvar_estkf + + SUBROUTINE c__PDAF3_assim_offline_en3dvar_lestkf(init_dim_obs_pdaf, & + obs_op_pdaf, cvt_ens_pdaf, cvt_adj_ens_pdaf, obs_op_lin_pdaf, & + obs_op_adj_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_en3dvar_lestkf(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_en3dvar_lestkf + + SUBROUTINE c__PDAF3_assim_offline_hyb3dvar(init_dim_obs_pdaf, obs_op_pdaf, & + cvt_ens_pdaf, cvt_adj_ens_pdaf, cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, & + obs_op_adj_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_hyb3dvar(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_hyb3dvar + + SUBROUTINE c__PDAF3_assim_offline_hyb3dvar_estkf(init_dim_obs_pdaf, & + obs_op_pdaf, cvt_ens_pdaf, cvt_adj_ens_pdaf, cvt_pdaf, cvt_adj_pdaf, & + obs_op_lin_pdaf, obs_op_adj_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_hyb3dvar_estkf(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_hyb3dvar_estkf + + SUBROUTINE c__PDAF3_assim_offline_hyb3dvar_lestkf(init_dim_obs_pdaf, & + obs_op_pdaf, cvt_ens_pdaf, cvt_adj_ens_pdaf, cvt_pdaf, cvt_adj_pdaf, & + obs_op_lin_pdaf, obs_op_adj_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_hyb3dvar_lestkf(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_hyb3dvar_lestkf + + SUBROUTINE c__PDAF3_assim_offline_3dvar_nondiagR(init_dim_obs_pdaf, & + obs_op_pdaf, prodrinva_pdaf, cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, & + obs_op_adj_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_3dvar_nondiagR(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__prodrinva_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_3dvar_nondiagR + + SUBROUTINE c__PDAF3_assim_offline_en3dvar_estkf_nondiagR(init_dim_obs_pdaf, & + obs_op_pdaf, prodrinva_pdaf, cvt_ens_pdaf, cvt_adj_ens_pdaf, & + obs_op_lin_pdaf, obs_op_adj_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_en3dvar_estkf_nondiagR(f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_en3dvar_estkf_nondiagR + + SUBROUTINE c__PDAF3_assim_offline_en3dvar_lestkf_nondiagR(init_dim_obs_pdaf, & + obs_op_pdaf, prodrinva_pdaf, cvt_ens_pdaf, cvt_adj_ens_pdaf, & + obs_op_lin_pdaf, obs_op_adj_pdaf, prodrinva_l_pdaf, init_n_domains_pdaf, & + init_dim_l_pdaf, init_dim_obs_l_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide product R^-1 A and apply localizations + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_en3dvar_lestkf_nondiagR(f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__prodrinva_l_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_en3dvar_lestkf_nondiagR + + SUBROUTINE c__PDAF3_assim_offline_hyb3dvar_estkf_nondiagR(init_dim_obs_pdaf, & + obs_op_pdaf, prodrinva_pdaf, cvt_ens_pdaf, cvt_adj_ens_pdaf, cvt_pdaf, & + cvt_adj_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, prepoststep_pdaf, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_hyb3dvar_estkf_nondiagR(f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__cvt_pdaf, & + f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_hyb3dvar_estkf_nondiagR + + SUBROUTINE c__PDAF3_assim_offline_hyb3dvar_lestkf_nondiagR( & + init_dim_obs_pdaf, obs_op_pdaf, prodrinva_pdaf, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, & + obs_op_adj_pdaf, prodrinva_l_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide product R^-1 A and apply localizations + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_hyb3dvar_lestkf_nondiagR(f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__cvt_pdaf, & + f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__prodrinva_l_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_hyb3dvar_lestkf_nondiagR + + SUBROUTINE c__PDAF3_assimilate(collect_state_pdaf, distribute_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, prepoststep_pdaf, next_observation_pdaf, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate + + SUBROUTINE c__PDAF3_assimilate_local(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, & + init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdaf, & + g2l_state_pdaf, l2g_state_pdaf, prepoststep_pdaf, next_observation_pdaf, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! Get local state from full state + procedure(c__g2l_state_pdaf) :: g2l_state_pdaf + ! Init full state from local state + procedure(c__l2g_state_pdaf) :: l2g_state_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + g2l_state_pdaf_c_ptr => g2l_state_pdaf + l2g_state_pdaf_c_ptr => l2g_state_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_local(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, f__l2g_state_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_local + + SUBROUTINE c__PDAF3_assimilate_global(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, prepoststep_pdaf, & + next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_global(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_global + + SUBROUTINE c__PDAF3_assimilate_lenkf(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, localize_pdaf, & + prepoststep_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply localization to HP and HPH^T + procedure(c__localize_covar_pdaf) :: localize_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + localize_covar_pdaf_c_ptr => localize_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_lenkf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__localize_covar_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_lenkf + + SUBROUTINE c__PDAF3_assimilate_ensrf(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, & + localize_serial_pdaf, prepoststep_pdaf, next_observation_pdaf, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply localization to HP and BXY for single observation + procedure(c__localize_covar_serial_pdaf) :: localize_serial_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + localize_covar_serial_pdaf_c_ptr => localize_serial_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_ensrf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__localize_covar_serial_pdaf, & + f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_ensrf + + SUBROUTINE c__PDAF3_assim_offline(init_dim_obs_pdaf, obs_op_pdaf, & + init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdaf, & + prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline + + SUBROUTINE c__PDAF3_assim_offline_local(init_dim_obs_pdaf, obs_op_pdaf, & + init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdaf, & + g2l_state_pdaf, l2g_state_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! Get local state from full state + procedure(c__g2l_state_pdaf) :: g2l_state_pdaf + ! Init full state from local state + procedure(c__l2g_state_pdaf) :: l2g_state_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + g2l_state_pdaf_c_ptr => g2l_state_pdaf + l2g_state_pdaf_c_ptr => l2g_state_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_local(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__g2l_state_pdaf, f__l2g_state_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_local + + SUBROUTINE c__PDAF3_assim_offline_global(init_dim_obs_pdaf, obs_op_pdaf, & + prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_global(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_global + + SUBROUTINE c__PDAF3_assim_offline_lenkf(init_dim_obs_pdaf, obs_op_pdaf, & + localize_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply localization to HP and HPH^T + procedure(c__localize_covar_pdaf) :: localize_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + localize_covar_pdaf_c_ptr => localize_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_lenkf(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__localize_covar_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_lenkf + + SUBROUTINE c__PDAF3_assim_offline_ensrf(init_dim_obs_pdaf, obs_op_pdaf, & + localize_serial_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply localization to HP and BXY for single observation + procedure(c__localize_covar_serial_pdaf) :: localize_serial_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + localize_covar_serial_pdaf_c_ptr => localize_serial_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_ensrf(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__localize_covar_serial_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_ensrf + + SUBROUTINE c__PDAF3_assim_offline_local_nondiagR(init_dim_obs_pdaf, & + obs_op_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdaf, & + prodrinva_l_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! Provide product of inverse of R with matrix A + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_local_nondiagR(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__prodrinva_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_local_nondiagR + + SUBROUTINE c__PDAF3_assim_offline_global_nondiagR(init_dim_obs_pdaf, & + obs_op_pdaf, prodrinva_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide product of inverse of R with matrix A + procedure(c__prodrinva_pdaf) :: prodrinva_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_global_nondiagR(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__prodrinva_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_global_nondiagR + + SUBROUTINE c__PDAF3_assim_offline_lnetf_nondiagR(init_dim_obs_pdaf, & + obs_op_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, likelihood_l_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! Compute likelihood and apply localization + procedure(c__likelihood_l_pdaf) :: likelihood_l_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + likelihood_l_pdaf_c_ptr => likelihood_l_pdaf + + call PDAF3_assim_offline_lnetf_nondiagR(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__likelihood_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_lnetf_nondiagR + + SUBROUTINE c__PDAF3_assim_offline_lknetf_nondiagR(init_dim_obs_pdaf, & + obs_op_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, prodrinva_l_pdaf, prodrinva_hyb_l_pdaf, & + likelihood_l_pdaf, likelihood_hyb_l_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! Provide product of inverse of R with matrix A + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdaf + ! Product R^-1 A on local analysis domain with hybrid weight + procedure(c__prodrinva_hyb_l_pdaf) :: prodrinva_hyb_l_pdaf + ! Compute likelihood and apply localization + procedure(c__likelihood_l_pdaf) :: likelihood_l_pdaf + ! Compute likelihood and apply localization with tempering + procedure(c__likelihood_hyb_l_pdaf) :: likelihood_hyb_l_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdaf + prodrinva_hyb_l_pdaf_c_ptr => prodrinva_hyb_l_pdaf + likelihood_l_pdaf_c_ptr => likelihood_l_pdaf + likelihood_hyb_l_pdaf_c_ptr => likelihood_hyb_l_pdaf + + call PDAF3_assim_offline_lknetf_nondiagR(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__prodrinva_l_pdaf, f__prodrinva_hyb_l_pdaf, & + f__likelihood_l_pdaf, f__likelihood_hyb_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_lknetf_nondiagR + + SUBROUTINE c__PDAF3_assim_offline_enkf_nondiagR(init_dim_obs_pdaf, & + obs_op_pdaf, add_obs_error_pdaf, init_obscovar_pdaf, prepoststep_pdaf, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Add observation error covariance matrix + procedure(c__add_obs_err_pdaf) :: add_obs_error_pdaf + ! Initialize mean observation error variance + procedure(c__init_obs_covar_pdaf) :: init_obscovar_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + add_obs_err_pdaf_c_ptr => add_obs_error_pdaf + init_obs_covar_pdaf_c_ptr => init_obscovar_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_enkf_nondiagR(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__add_obs_err_pdaf, f__init_obs_covar_pdaf, f__prepoststep_pdaf, outflag) + END SUBROUTINE c__PDAF3_assim_offline_enkf_nondiagR + + SUBROUTINE c__PDAF3_assim_offline_lenkf_nondiagR(init_dim_obs_pdaf, & + obs_op_pdaf, localize_pdaf, add_obs_error_pdaf, & + init_obscovar_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Apply covariance localization + procedure(c__localize_covar_pdaf) :: localize_pdaf + ! Add observation error covariance matrix + procedure(c__add_obs_err_pdaf) :: add_obs_error_pdaf + ! Initialize mean observation error variance + procedure(c__init_obs_covar_pdaf) :: init_obscovar_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + localize_covar_pdaf_c_ptr => localize_pdaf + add_obs_err_pdaf_c_ptr => add_obs_error_pdaf + init_obs_covar_pdaf_c_ptr => init_obscovar_pdaf + + call PDAF3_assim_offline_lenkf_nondiagR(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__localize_covar_pdaf, f__add_obs_err_pdaf, & + f__init_obs_covar_pdaf, f__prepoststep_pdaf, outflag) + END SUBROUTINE c__PDAF3_assim_offline_lenkf_nondiagR + + SUBROUTINE c__PDAF3_assim_offline_nonlin_nondiagR(init_dim_obs_pdaf, & + obs_op_pdaf, likelihood_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Compute likelihood + procedure(c__likelihood_pdaf) :: likelihood_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + likelihood_pdaf_c_ptr => likelihood_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_assim_offline_nonlin_nondiagR(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__likelihood_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assim_offline_nonlin_nondiagR + + SUBROUTINE c__PDAF3_assimilate_3dvar_all(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, & + obs_op_adj_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, prepoststep_pdaf, next_observation_pdaf, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_3dvar_all(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_3dvar_all + + SUBROUTINE c__PDAF3_assimilate_3dvar(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, cvt_pdaf, & + cvt_adj_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, prepoststep_pdaf, & + next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_3dvar(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_3dvar + + SUBROUTINE c__PDAF3_assimilate_en3dvar(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, init_n_domains_pdaf, & + init_dim_l_pdaf, init_dim_obs_l_pdaf, prepoststep_pdaf, & + next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_en3dvar(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_en3dvar + + SUBROUTINE c__PDAF3_assimilate_en3dvar_estkf(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, prepoststep_pdaf, & + next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_en3dvar_estkf(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_en3dvar_estkf + + SUBROUTINE c__PDAF3_assimilate_en3dvar_lestkf(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, init_n_domains_pdaf, & + init_dim_l_pdaf, init_dim_obs_l_pdaf, prepoststep_pdaf, & + next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_en3dvar_lestkf(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_en3dvar_lestkf + + SUBROUTINE c__PDAF3_assimilate_hyb3dvar(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, & + obs_op_adj_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, prepoststep_pdaf, next_observation_pdaf, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_hyb3dvar(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, & + f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_hyb3dvar + + SUBROUTINE c__PDAF3_assimilate_hyb3dvar_estkf(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, & + obs_op_adj_pdaf, prepoststep_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_hyb3dvar_estkf(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_hyb3dvar_estkf + + SUBROUTINE c__PDAF3_assimilate_hyb3dvar_lestkf(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, & + obs_op_adj_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, prepoststep_pdaf, next_observation_pdaf, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_hyb3dvar_lestkf(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_hyb3dvar_lestkf + + SUBROUTINE c__PDAF3_assimilate_local_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, & + init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdaf, & + prodrinva_l_pdaf, prepoststep_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! Provide product of inverse of R with matrix A + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_local_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__prodrinva_l_pdaf, f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_local_nondiagR + + SUBROUTINE c__PDAF3_assimilate_global_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, prodrinva_pdaf, & + prepoststep_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide product of inverse of R with matrix A + procedure(c__prodrinva_pdaf) :: prodrinva_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_global_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, & + f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_global_nondiagR + + SUBROUTINE c__PDAF3_assimilate_lnetf_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, & + init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdaf, & + likelihood_l_pdaf, prepoststep_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! Compute likelihood and apply localization + procedure(c__likelihood_l_pdaf) :: likelihood_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + likelihood_l_pdaf_c_ptr => likelihood_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_lnetf_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__likelihood_l_pdaf, f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_lnetf_nondiagR + + SUBROUTINE c__PDAF3_assimilate_lknetf_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, & + init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdaf, & + prodrinva_l_pdaf, prodrinva_hyb_l_pdaf, likelihood_l_pdaf, & + likelihood_hyb_l_pdaf, prepoststep_pdaf, next_observation_pdaf, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! Provide product of inverse of R with matrix A + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdaf + ! Product R^-1 A on local analysis domain with hybrid weight + procedure(c__prodrinva_hyb_l_pdaf) :: prodrinva_hyb_l_pdaf + ! Compute likelihood and apply localization + procedure(c__likelihood_l_pdaf) :: likelihood_l_pdaf + ! Compute likelihood and apply localization with tempering + procedure(c__likelihood_hyb_l_pdaf) :: likelihood_hyb_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdaf + prodrinva_hyb_l_pdaf_c_ptr => prodrinva_hyb_l_pdaf + likelihood_l_pdaf_c_ptr => likelihood_l_pdaf + likelihood_hyb_l_pdaf_c_ptr => likelihood_hyb_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_lknetf_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__prodrinva_l_pdaf, f__prodrinva_hyb_l_pdaf, f__likelihood_l_pdaf, & + f__likelihood_hyb_l_pdaf, f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_lknetf_nondiagR + + SUBROUTINE c__PDAF3_assimilate_enkf_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, & + add_obs_error_pdaf, init_obscovar_pdaf, prepoststep_pdaf, & + next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Add observation error covariance matrix + procedure(c__add_obs_err_pdaf) :: add_obs_error_pdaf + ! Initialize mean observation error variance + procedure(c__init_obs_covar_pdaf) :: init_obscovar_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + add_obs_err_pdaf_c_ptr => add_obs_error_pdaf + init_obs_covar_pdaf_c_ptr => init_obscovar_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_enkf_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__add_obs_err_pdaf, f__init_obs_covar_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + END SUBROUTINE c__PDAF3_assimilate_enkf_nondiagR + + SUBROUTINE c__PDAF3_assimilate_lenkf_nondiagR(collect_state_pdaf, distribute_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, localize_pdaf, & + add_obs_error_pdaf, init_obscovar_pdaf, prepoststep_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Apply covariance localization + procedure(c__localize_covar_pdaf) :: localize_pdaf + ! Add observation error covariance matrix + procedure(c__add_obs_err_pdaf) :: add_obs_error_pdaf + ! Initialize mean observation error variance + procedure(c__init_obs_covar_pdaf) :: init_obscovar_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + localize_covar_pdaf_c_ptr => localize_pdaf + add_obs_err_pdaf_c_ptr => add_obs_error_pdaf + init_obs_covar_pdaf_c_ptr => init_obscovar_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_lenkf_nondiagR(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__localize_covar_pdaf, & + f__add_obs_err_pdaf, f__init_obs_covar_pdaf, f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + END SUBROUTINE c__PDAF3_assimilate_lenkf_nondiagR + + SUBROUTINE c__PDAF3_assimilate_nonlin_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, likelihood_pdaf, & + prepoststep_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Compute likelihood + procedure(c__likelihood_pdaf) :: likelihood_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + likelihood_pdaf_c_ptr => likelihood_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_assimilate_nonlin_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__likelihood_pdaf, f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_assimilate_nonlin_nondiagR + + SUBROUTINE c__PDAF3_generate_obs(collect_state_pdaf, distribute_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, get_obs_pdaf, prepoststep_pdaf, & + next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Initialize observation vector + procedure(c__get_obs_f_pdaf) :: get_obs_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + get_obs_f_pdaf_c_ptr => get_obs_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAF3_generate_obs(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__get_obs_f_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF3_generate_obs + + SUBROUTINE c__PDAF3_generate_obs_offline(init_dim_obs_pdaf, obs_op_pdaf, & + get_obs_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Initialize observation vector + procedure(c__get_obs_f_pdaf) :: get_obs_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + get_obs_f_pdaf_c_ptr => get_obs_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_generate_obs_offline(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__get_obs_f_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_generate_obs_offline +end MODULE pdaf3_c_assim diff --git a/pyPDAF/source/src/fortran/pdaf3_c_put.f90 b/pyPDAF/source/src/fortran/pdaf3_c_put.f90 new file mode 100644 index 0000000000000000000000000000000000000000..e196ffec0d4fc0e560aa5b762f8667c3465892c7 --- /dev/null +++ b/pyPDAF/source/src/fortran/pdaf3_c_put.f90 @@ -0,0 +1,1103 @@ +MODULE pdaf3_c_put +use iso_c_binding, only: c_int, c_double, c_bool +use PDAF +use pdaf_c_cb_interface +use pdaf_c_f_interface + +implicit none + +contains + SUBROUTINE c__PDAF3_put_state_3dvar_nondiagR(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, prodrinva_pdaf, cvt_pdaf, cvt_adj_pdaf, & + obs_op_lin_pdaf, obs_op_adj_pdaf, prepoststep_pdaf, outflag) bind(c) + implicit none + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_3dvar_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, f__cvt_pdaf, & + f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_3dvar_nondiagR + + SUBROUTINE c__PDAF3_put_state_en3dvar_estkf_nondiagR(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, prodrinva_pdaf, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, prepoststep_pdaf, & + outflag) bind(c) + implicit none + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_en3dvar_estkf_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__prepoststep_pdaf, & + outflag) + + END SUBROUTINE c__PDAF3_put_state_en3dvar_estkf_nondiagR + + SUBROUTINE c__PDAF3_put_state_en3dvar_lestkf_nondiagR(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, prodrinva_pdaf, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, prodrinva_l_pdaf, & + init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdaf, & + prepoststep_pdaf, outflag) bind(c) + implicit none + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide product R^-1 A and apply localizations + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_en3dvar_lestkf_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__prodrinva_l_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_en3dvar_lestkf_nondiagR + + SUBROUTINE c__PDAF3_put_state_hyb3dvar_estkf_nondiagR(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, prodrinva_pdaf, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, & + obs_op_adj_pdaf, prepoststep_pdaf, outflag) bind(c) + implicit none + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_hyb3dvar_estkf_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_hyb3dvar_estkf_nondiagR + + SUBROUTINE c__PDAF3_put_state_hyb3dvar_lestkf_nondiagR(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, prodrinva_pdaf, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, & + obs_op_adj_pdaf, prodrinva_l_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, prepoststep_pdaf, outflag) bind(c) + implicit none + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide product R^-1 A and apply localizations + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_hyb3dvar_lestkf_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_hyb3dvar_lestkf_nondiagR + + SUBROUTINE c__PDAF3_put_state_3dvar_all(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, cvt_ens_pdaf, cvt_adj_ens_pdaf, cvt_pdaf, & + cvt_adj_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, init_n_domains_pdaf, & + init_dim_l_pdaf, init_dim_obs_l_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_3dvar_all(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_3dvar_all + + SUBROUTINE c__PDAF3_put_state_3dvar(collect_state_pdaf, init_dim_obs_pdaf, & + obs_op_pdaf, cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, & + prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_3dvar(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_3dvar + + SUBROUTINE c__PDAF3_put_state_en3dvar(collect_state_pdaf, init_dim_obs_pdaf, & + obs_op_pdaf, cvt_ens_pdaf, cvt_adj_ens_pdaf, obs_op_lin_pdaf, & + obs_op_adj_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_en3dvar(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_en3dvar + + SUBROUTINE c__PDAF3_put_state_en3dvar_estkf(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, cvt_ens_pdaf, cvt_adj_ens_pdaf, & + obs_op_lin_pdaf, obs_op_adj_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_en3dvar_estkf(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_en3dvar_estkf + + SUBROUTINE c__PDAF3_put_state_en3dvar_lestkf(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, cvt_ens_pdaf, cvt_adj_ens_pdaf, & + obs_op_lin_pdaf, obs_op_adj_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_en3dvar_lestkf(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_en3dvar_lestkf + + SUBROUTINE c__PDAF3_put_state_hyb3dvar(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, cvt_ens_pdaf, cvt_adj_ens_pdaf, cvt_pdaf, & + cvt_adj_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, init_n_domains_pdaf, & + init_dim_l_pdaf, init_dim_obs_l_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_hyb3dvar(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_hyb3dvar + + SUBROUTINE c__PDAF3_put_state_hyb3dvar_estkf(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, cvt_ens_pdaf, cvt_adj_ens_pdaf, cvt_pdaf, & + cvt_adj_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, prepoststep_pdaf, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_hyb3dvar_estkf(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, & + f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_hyb3dvar_estkf + + SUBROUTINE c__PDAF3_put_state_hyb3dvar_lestkf(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, cvt_ens_pdaf, cvt_adj_ens_pdaf, cvt_pdaf, & + cvt_adj_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, init_n_domains_pdaf, & + init_dim_l_pdaf, init_dim_obs_l_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_hyb3dvar_lestkf(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, & + f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_hyb3dvar_lestkf + + SUBROUTINE c__PDAF3_put_state_local_nondiagR(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, init_n_domains_pdaf, & + init_dim_l_pdaf, init_dim_obs_l_pdaf, prodrinva_l_pdaf, & + prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! Provide product of inverse of R with matrix A + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdaf + + call PDAF3_put_state_local_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__prodrinva_l_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_local_nondiagR + + SUBROUTINE c__PDAF3_put_state_global_nondiagR(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, prodrinva_pdaf, prepoststep_pdaf, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide product of inverse of R with matrix A + procedure(c__prodrinva_pdaf) :: prodrinva_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_global_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_global_nondiagR + + SUBROUTINE c__PDAF3_put_state_lnetf_nondiagR(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, init_n_domains_pdaf, & + init_dim_l_pdaf, init_dim_obs_l_pdaf, likelihood_l_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! Compute likelihood and apply localization + procedure(c__likelihood_l_pdaf) :: likelihood_l_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + likelihood_l_pdaf_c_ptr => likelihood_l_pdaf + + call PDAF3_put_state_lnetf_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__likelihood_l_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_lnetf_nondiagR + + SUBROUTINE c__PDAF3_put_state_lknetf_nondiagR(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, init_n_domains_pdaf, & + init_dim_l_pdaf, init_dim_obs_l_pdaf, prodrinva_l_pdaf, & + prodrinva_hyb_l_pdaf, likelihood_l_pdaf, likelihood_hyb_l_pdaf, & + prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! Provide product of inverse of R with matrix A + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdaf + ! Product R^-1 A on local analysis domain with hybrid weight + procedure(c__prodrinva_hyb_l_pdaf) :: prodrinva_hyb_l_pdaf + ! Compute likelihood and apply localization + procedure(c__likelihood_l_pdaf) :: likelihood_l_pdaf + ! Compute likelihood and apply localization with tempering + procedure(c__likelihood_hyb_l_pdaf) :: likelihood_hyb_l_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdaf + prodrinva_hyb_l_pdaf_c_ptr => prodrinva_hyb_l_pdaf + likelihood_l_pdaf_c_ptr => likelihood_l_pdaf + likelihood_hyb_l_pdaf_c_ptr => likelihood_hyb_l_pdaf + + call PDAF3_put_state_lknetf_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__prodrinva_l_pdaf, & + f__prodrinva_hyb_l_pdaf, f__likelihood_l_pdaf, & + f__likelihood_hyb_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_lknetf_nondiagR + + SUBROUTINE c__PDAF3_put_state_enkf_nondiagR(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, add_obs_error_pdaf, init_obscovar_pdaf, & + prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Add observation error covariance matrix + procedure(c__add_obs_err_pdaf) :: add_obs_error_pdaf + ! Initialize mean observation error variance + procedure(c__init_obs_covar_pdaf) :: init_obscovar_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + add_obs_err_pdaf_c_ptr => add_obs_error_pdaf + init_obs_covar_pdaf_c_ptr => init_obscovar_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_enkf_nondiagR(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__add_obs_err_pdaf, f__init_obs_covar_pdaf, f__prepoststep_pdaf, & + outflag) + END SUBROUTINE c__PDAF3_put_state_enkf_nondiagR + + SUBROUTINE c__PDAF3_put_state_lenkf_nondiagR(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, localize_pdaf, & + add_obs_error_pdaf, init_obscovar_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Apply covariance localization + procedure(c__localize_covar_pdaf) :: localize_pdaf + ! Add observation error covariance matrix + procedure(c__add_obs_err_pdaf) :: add_obs_error_pdaf + ! Initialize mean observation error variance + procedure(c__init_obs_covar_pdaf) :: init_obscovar_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + localize_covar_pdaf_c_ptr => localize_pdaf + add_obs_err_pdaf_c_ptr => add_obs_error_pdaf + init_obs_covar_pdaf_c_ptr => init_obscovar_pdaf + + call PDAF3_put_state_lenkf_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__localize_covar_pdaf, & + f__add_obs_err_pdaf, f__init_obs_covar_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_lenkf_nondiagR + + SUBROUTINE c__PDAF3_put_state_nonlin_nondiagR(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, likelihood_pdaf, prepoststep_pdaf, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Compute likelihood + procedure(c__likelihood_pdaf) :: likelihood_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + likelihood_pdaf_c_ptr => likelihood_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_nonlin_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__likelihood_pdaf, f__prepoststep_pdaf, & + outflag) + + END SUBROUTINE c__PDAF3_put_state_nonlin_nondiagR + + SUBROUTINE c__PDAF3_put_state(collect_state_pdaf, init_dim_obs_pdaf, & + obs_op_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdaf, & + prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state(f__collect_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state + + SUBROUTINE c__PDAF3_put_state_local(collect_state_pdaf, init_dim_obs_pdaf, & + obs_op_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdaf, & + g2l_state_pdaf, l2g_state_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! Get local state from full state + procedure(c__g2l_state_pdaf) :: g2l_state_pdaf + ! Init full state from local state + procedure(c__l2g_state_pdaf) :: l2g_state_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + g2l_state_pdaf_c_ptr => g2l_state_pdaf + l2g_state_pdaf_c_ptr => l2g_state_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_local(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, f__l2g_state_pdaf, f__prepoststep_pdaf, & + outflag) + + END SUBROUTINE c__PDAF3_put_state_local + + SUBROUTINE c__PDAF3_put_state_global(collect_state_pdaf, init_dim_obs_pdaf, & + obs_op_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_global(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_global + + SUBROUTINE c__PDAF3_put_state_lenkf(collect_state_pdaf, init_dim_obs_pdaf, & + obs_op_pdaf, localize_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply localization to HP and HPH^T + procedure(c__localize_covar_pdaf) :: localize_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + localize_covar_pdaf_c_ptr => localize_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_lenkf(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__localize_covar_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_lenkf + + SUBROUTINE c__PDAF3_put_state_ensrf(collect_state_pdaf, init_dim_obs_pdaf, & + obs_op_pdaf, localize_serial_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply localization to HP and BXY for single observation + procedure(c__localize_covar_serial_pdaf) :: localize_serial_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + localize_covar_serial_pdaf_c_ptr => localize_serial_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_ensrf(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__localize_covar_serial_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_ensrf + + SUBROUTINE c__PDAF3_put_state_generate_obs(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, get_obs_pdaf, prepoststep_pdaf, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Initialize observation vector + procedure(c__get_obs_f_pdaf) :: get_obs_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + get_obs_f_pdaf_c_ptr => get_obs_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAF3_put_state_generate_obs(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__get_obs_f_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF3_put_state_generate_obs + +END MODULE pdaf3_c_put diff --git a/pyPDAF/source/src/fortran/pdaf_c.f90 b/pyPDAF/source/src/fortran/pdaf_c.f90 new file mode 100644 index 0000000000000000000000000000000000000000..d081e8ab9c6066bbbc36083c346eaa21da9b0600 --- /dev/null +++ b/pyPDAF/source/src/fortran/pdaf_c.f90 @@ -0,0 +1,356 @@ +module pdaf_c +use iso_c_binding, only: c_int, c_double, c_bool +use pdaf +use pdaf_c_cb_interface +implicit none + +contains + SUBROUTINE c__PDAF_get_fcst_info(steps, time, doexit) bind(c) + ! Flag and number of time steps + INTEGER(c_int), INTENT(inout) :: steps + ! current model time + REAL(c_double), INTENT(inout) :: time + ! Whether to exit from forecasts + INTEGER(c_int), INTENT(inout) :: doexit + + + call PDAF_get_fcst_info(steps, time, doexit) + + END SUBROUTINE c__PDAF_get_fcst_info + + SUBROUTINE c__PDAF_correlation_function(ctype, length, distance, value) bind(c) + ! Type of correlation function + INTEGER(c_int), INTENT(in) :: ctype + ! Length scale of function + REAL(c_double), INTENT(in) :: length + ! Distance at which the function is evaluated + REAL(c_double), INTENT(in) :: distance + ! Value of the function + REAL(c_double), INTENT(out) :: value + + + call PDAF_correlation_function(ctype, length, distance, value) + + END SUBROUTINE c__PDAF_correlation_function + + SUBROUTINE c__PDAF_deallocate() bind(c) + call PDAF_deallocate() + + END SUBROUTINE c__PDAF_deallocate + + SUBROUTINE c__PDAF_eofcovar(dim, nstates, nfields, dim_fields, offsets, & + remove_mstate, do_mv, states, stddev, svals, svec, meanstate, verbose, & + status) bind(c) + ! Dimension of state vector + INTEGER(c_int), INTENT(in) :: dim + ! Number of state vectors + INTEGER(c_int), INTENT(in) :: nstates + ! Number of fields in state vector + INTEGER(c_int), INTENT(in) :: nfields + ! Size of each field + INTEGER(c_int), DIMENSION(nfields), INTENT(in) :: dim_fields + ! Start position of each field + INTEGER(c_int), DIMENSION(nfields), INTENT(in) :: offsets + ! 1: subtract mean state from states + INTEGER(c_int), INTENT(in) :: remove_mstate + ! 1: Do multivariate scaling; 0: no scaling + INTEGER(c_int), INTENT(in) :: do_mv + ! State perturbations + REAL(c_double), DIMENSION(dim, nstates), INTENT(inout) :: states + ! Standard deviation of field variability + REAL(c_double), DIMENSION(nfields), INTENT(out) :: stddev + ! Singular values divided by sqrt(nstates-1) + REAL(c_double), DIMENSION(nstates), INTENT(out) :: svals + ! Singular vectors + REAL(c_double), DIMENSION(dim, nstates), INTENT(out) :: svec + ! Mean state (only changed if remove_mstate=1) + REAL(c_double), DIMENSION(dim), INTENT(inout) :: meanstate + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: verbose + ! Status flag + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_eofcovar(dim, nstates, nfields, dim_fields, offsets, & + remove_mstate, do_mv, states, stddev, svals, svec, meanstate, verbose, & + status) + + END SUBROUTINE c__PDAF_eofcovar + + SUBROUTINE c__PDAF_force_analysis() bind(c) + call PDAF_force_analysis() + + END SUBROUTINE c__PDAF_force_analysis + + SUBROUTINE c__PDAF_gather_dim_obs_f(dim_obs_p, dim_obs_f) bind(c) + ! PE-local observation dimension + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Full observation dimension + INTEGER(c_int), INTENT(out) :: dim_obs_f + + + call PDAF_gather_dim_obs_f(dim_obs_p, dim_obs_f) + + END SUBROUTINE c__PDAF_gather_dim_obs_f + + SUBROUTINE c__PDAF_gather_obs_f(obs_p, obs_f, status) bind(c) + USE PDAF_mod_parallel, ONLY: dimobs_p, dimobs_f + implicit none + ! PE-local vector + REAL(c_double), DIMENSION(dimobs_p), INTENT(in) :: obs_p + ! Full gathered vector + REAL(c_double), DIMENSION(dimobs_f), INTENT(out) :: obs_f + ! Status flag: + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_gather_obs_f(obs_p, obs_f, status) + + END SUBROUTINE c__PDAF_gather_obs_f + + SUBROUTINE c__PDAF_gather_obs_f2(coords_p, coords_f, nrows, status) bind(c) + USE PDAF_mod_parallel, ONLY: dimobs_p, dimobs_f + + implicit none + ! PE-local array + REAL(c_double), DIMENSION(nrows, dimobs_p), INTENT(in) :: coords_p + ! Full gathered array + REAL(c_double), DIMENSION(nrows, dimobs_f), INTENT(out) :: coords_f + ! Number of rows in array + INTEGER(c_int), INTENT(in) :: nrows + ! Status flag: + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_gather_obs_f2(coords_p, coords_f, nrows, status) + + END SUBROUTINE c__PDAF_gather_obs_f2 + + SUBROUTINE c__PDAF_gather_obs_f_flex(dim_obs_p, dim_obs_f, obs_p, obs_f, & + status) bind(c) + ! PE-local observation dimension + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Full observation dimension + INTEGER(c_int), INTENT(in) :: dim_obs_f + ! PE-local vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Full gathered vector + REAL(c_double), DIMENSION(dim_obs_f), INTENT(out) :: obs_f + ! Status flag: (0) no error + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_gather_obs_f_flex(dim_obs_p, dim_obs_f, obs_p, obs_f, status) + + END SUBROUTINE c__PDAF_gather_obs_f_flex + + SUBROUTINE c__PDAF_gather_obs_f2_flex(dim_obs_p, dim_obs_f, coords_p, & + coords_f, nrows, status) bind(c) + ! PE-local observation dimension + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Full observation dimension + INTEGER(c_int), INTENT(in) :: dim_obs_f + ! PE-local array + REAL(c_double), DIMENSION(nrows, dim_obs_p), INTENT(in) :: coords_p + ! Full gathered array + REAL(c_double), DIMENSION(nrows, dim_obs_f), INTENT(out) :: coords_f + ! Number of rows in array + INTEGER(c_int), INTENT(in) :: nrows + ! Status flag: (0) no error + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_gather_obs_f2_flex(dim_obs_p, dim_obs_f, coords_p, coords_f, & + nrows, status) + + END SUBROUTINE c__PDAF_gather_obs_f2_flex + + SUBROUTINE c__PDAF_init(filtertype, subtype, stepnull, param_int, dim_pint, & + param_real, dim_preal, comm_model, comm_filter, comm_couple, task_id, & + n_modeltasks, in_filterpe, u_init_ens, in_screen, outflag) bind(c) + use pdaf_c_f_interface, only: init_ens_pdaf_c_ptr, & + f__init_ens_pdaf + implicit none + ! Type of filter + INTEGER(c_int), INTENT(in) :: filtertype + ! Sub-type of filter + INTEGER(c_int), INTENT(in) :: subtype + ! Initial time step of assimilation + INTEGER(c_int), INTENT(in) :: stepnull + ! Number of integer parameters + INTEGER(c_int), INTENT(in) :: dim_pint + ! Integer parameter array + INTEGER(c_int), DIMENSION(dim_pint), INTENT(inout) :: param_int + ! Number of real parameter + INTEGER(c_int), INTENT(in) :: dim_preal + ! Real parameter array + REAL(c_double), DIMENSION(dim_preal), INTENT(inout) :: param_real + ! Model communicator + INTEGER(c_int), INTENT(in) :: comm_model + ! Filter communicator + INTEGER(c_int), INTENT(in) :: comm_filter + ! Coupling communicator + INTEGER(c_int), INTENT(in) :: comm_couple + ! Id of my ensemble task + INTEGER(c_int), INTENT(in) :: task_id + ! Number of parallel model tasks + INTEGER(c_int), INTENT(in) :: n_modeltasks + ! Is my PE a filter-PE? + LOGICAL(c_bool), INTENT(in) :: in_filterpe + ! Control screen output: + INTEGER(c_int), INTENT(in) :: in_screen + ! Status flag, 0: no error, error codes: + INTEGER(c_int), INTENT(out) :: outflag + + ! User-supplied routine for ensemble initialization + procedure(c__init_ens_pdaf) :: u_init_ens + + init_ens_pdaf_c_ptr => u_init_ens + call PDAF_init(filtertype, subtype, stepnull, param_int, dim_pint, & + param_real, dim_preal, comm_model, comm_filter, comm_couple, task_id, & + n_modeltasks, logical(in_filterpe), f__init_ens_pdaf, in_screen, outflag) + + END SUBROUTINE c__PDAF_init + + SUBROUTINE c__PDAF_init_forecast(u_next_observation, u_distribute_state, & + u_prepoststep, outflag) bind(c) + use pdaf_c_f_interface, only: next_observation_pdaf_c_ptr, & + f__next_observation_pdaf, & + distribute_state_pdaf_c_ptr, & + f__distribute_state_pdaf, & + prepoststep_pdaf_c_ptr, & + f__prepoststep_pdaf + implicit none + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: u_next_observation + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + next_observation_pdaf_c_ptr => u_next_observation + distribute_state_pdaf_c_ptr => u_distribute_state + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAF_init_forecast(f__next_observation_pdaf, f__distribute_state_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF_init_forecast + + SUBROUTINE c__PDAF_local_weight(wtype, rtype, cradius, sradius, distance, & + nrows, ncols, a, var_obs, weight, verbose) bind(c) + ! Type of weight function + INTEGER(c_int), INTENT(in) :: wtype + ! Type of regulated weighting + INTEGER(c_int), INTENT(in) :: rtype + ! Cut-off radius + REAL(c_double), INTENT(in) :: cradius + ! Support radius + REAL(c_double), INTENT(in) :: sradius + ! Distance to observation + REAL(c_double), INTENT(in) :: distance + ! Number of rows in matrix A + INTEGER(c_int), INTENT(in) :: nrows + ! Number of columns in matrix A + INTEGER(c_int), INTENT(in) :: ncols + ! Input matrix + REAL(c_double), DIMENSION(nrows, ncols), INTENT(in) :: a + ! Observation variance + REAL(c_double), INTENT(in) :: var_obs + ! Weights + REAL(c_double), INTENT(out) :: weight + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAF_local_weight(wtype, rtype, cradius, sradius, distance, nrows, & + ncols, a, var_obs, weight, verbose) + + END SUBROUTINE c__PDAF_local_weight + + SUBROUTINE c__PDAF_local_weights(wtype, cradius, sradius, dim, distance, & + weight, verbose) bind(c) + ! Type of weight function + INTEGER(c_int), INTENT(in) :: wtype + ! Parameter for cut-off + REAL(c_double), INTENT(in) :: cradius + ! Support radius + REAL(c_double), INTENT(in) :: sradius + ! Size of distance and weight arrays + INTEGER(c_int), INTENT(in) :: dim + ! Array holding distances + REAL(c_double), DIMENSION(dim), INTENT(in) :: distance + ! Array for weights + REAL(c_double), DIMENSION(dim), INTENT(out) :: weight + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAF_local_weights(wtype, cradius, sradius, dim, distance, weight, & + verbose) + + END SUBROUTINE c__PDAF_local_weights + + SUBROUTINE c__PDAF_print_filter_types(verbose) bind(c) + ! + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAF_print_filter_types(verbose) + + END SUBROUTINE c__PDAF_print_filter_types + + SUBROUTINE c__PDAF_print_DA_types(verbose) bind(c) + ! + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAF_print_DA_types(verbose) + + END SUBROUTINE c__PDAF_print_DA_types + + SUBROUTINE c__PDAF_print_info(printtype) bind(c) + ! Type of screen output: + INTEGER(c_int), INTENT(in) :: printtype + + + call PDAF_print_info(printtype) + + END SUBROUTINE c__PDAF_print_info + + SUBROUTINE c__PDAF_reset_forget(forget_in) bind(c) + ! New value of forgetting factor + REAL(c_double), INTENT(in) :: forget_in + + + call PDAF_reset_forget(forget_in) + + END SUBROUTINE c__PDAF_reset_forget + + SUBROUTINE c__PDAF_SampleEns(dim, dim_ens, modes, svals, state, ens, & + verbose, flag) bind(c) + ! Size of state vector + INTEGER(c_int), INTENT(in) :: dim + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Array of EOF modes + REAL(c_double), DIMENSION(dim, dim_ens-1), INTENT(inout) :: modes + ! Vector of singular values + REAL(c_double), DIMENSION(dim_ens-1), INTENT(in) :: svals + ! PE-local model state + REAL(c_double), DIMENSION(dim), INTENT(inout) :: state + ! State ensemble + REAL(c_double), DIMENSION(dim, dim_ens), INTENT(out) :: ens + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: verbose + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + + call PDAF_SampleEns(dim, dim_ens, modes, svals, state, ens, verbose, flag) + + END SUBROUTINE c__PDAF_SampleEns +end module pdaf_c diff --git a/pyPDAF/source/src/fortran/pdaf_c_assim.f90 b/pyPDAF/source/src/fortran/pdaf_c_assim.f90 new file mode 100644 index 0000000000000000000000000000000000000000..bc37fdd66a408c8e0ccf3406a1970700638db223 --- /dev/null +++ b/pyPDAF/source/src/fortran/pdaf_c_assim.f90 @@ -0,0 +1,2018 @@ +MODULE pdaf_c_assim +use iso_c_binding, only: c_int, c_double, c_bool +use PDAF +! use PDAF_analysis_utils +use pdaf_c_cb_interface +use pdaf_c_f_interface + +implicit none + +contains + SUBROUTINE c__PDAF_get_state(steps, time, doexit, u_next_observation, & + u_distribute_state, u_prepoststep, outflag) bind(c) + ! Flag and number of time steps + INTEGER(c_int), INTENT(inout) :: steps + ! current model time1 + REAL(c_double), INTENT(out) :: time + ! Whether to exit from forecasts + INTEGER(c_int), INTENT(inout) :: doexit + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + ! Provide information on next forecast + procedure(c__next_observation_pdaf) :: u_next_observation + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + next_observation_pdaf_c_ptr => u_next_observation + distribute_state_pdaf_c_ptr => u_distribute_state + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAF_get_state(steps, time, doexit, f__next_observation_pdaf, & + f__distribute_state_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF_get_state + + SUBROUTINE c__PDAF_assimilate_estkf(u_collect_state, u_distribute_state, & + u_init_dim_obs, u_obs_op, u_init_obs, u_prepoststep, u_prodrinva, & + u_init_obsvar, u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_pdaf_c_ptr => u_prodrinva + init_obsvar_pdaf_c_ptr => u_init_obsvar + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_assimilate_estkf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, & + f__prepoststep_pdaf, f__prodrinva_pdaf, & + f__init_obsvar_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_assimilate_estkf + + SUBROUTINE c__PDAF_assim_offline_estkf(u_init_dim_obs, u_obs_op, u_init_obs, & + u_prepoststep, u_prodrinva, u_init_obsvar, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_pdaf_c_ptr => u_prodrinva + init_obsvar_pdaf_c_ptr => u_init_obsvar + + call PDAF_assim_offline_estkf(f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, & + f__prepoststep_pdaf, f__prodrinva_pdaf, f__init_obsvar_pdaf, outflag) + + END SUBROUTINE c__PDAF_assim_offline_estkf + + SUBROUTINE c__PDAF_assimilate_3dvar(u_collect_state, u_distribute_state, & + u_init_dim_obs, u_obs_op, u_init_obs, u_prodrinva, u_cvt, u_cvt_adj, & + u_obs_op_lin, u_obs_op_adj, u_prepoststep, u_next_observation, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + prepoststep_pdaf_c_ptr => u_prepoststep + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_assimilate_3dvar(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, & + f__prodrinva_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_assimilate_3dvar + + SUBROUTINE c__PDAF_assim_offline_3dvar(u_init_dim_obs, u_obs_op, u_init_obs, & + u_prodrinva, u_cvt, u_cvt_adj, u_obs_op_lin, u_obs_op_adj, u_prepoststep, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAF_assim_offline_3dvar(f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, & + f__prodrinva_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF_assim_offline_3dvar + + SUBROUTINE c__PDAF_assimilate_en3dvar_lestkf(u_collect_state, & + u_distribute_state, u_init_dim_obs, u_obs_op, u_init_obs, u_prodrinva, & + u_cvt_ens, u_cvt_adj_ens, u_obs_op_lin, u_obs_op_adj, u_init_dim_obs_f, & + u_obs_op_f, u_init_obs_f, u_init_obs_l, u_prodrinva_l, & + u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, u_g2l_state, & + u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, u_prepoststep, & + u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble var) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs_f + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_f + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs_f + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + init_dim_obs_f_pdaf_c_ptr => u_init_dim_obs_f + obs_op_f_pdaf_c_ptr => u_obs_op_f + init_obs_f_pdaf_c_ptr => u_init_obs_f + init_obs_l_pdaf_c_ptr => u_init_obs_l + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + prepoststep_pdaf_c_ptr => u_prepoststep + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_assimilate_en3dvar_lestkf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, & + f__prodrinva_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__init_dim_obs_f_pdaf, & + f__obs_op_f_pdaf, f__init_obs_f_pdaf, f__init_obs_l_pdaf, & + f__prodrinva_l_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__g2l_state_pdaf, & + f__l2g_state_pdaf, f__g2l_obs_pdaf, f__init_obsvar_pdaf, & + f__init_obsvar_l_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_assimilate_en3dvar_lestkf + + SUBROUTINE c__PDAF_assim_offline_en3dvar_lestkf(u_init_dim_obs, u_obs_op, & + u_init_obs, u_prodrinva, u_cvt_ens, u_cvt_adj_ens, u_obs_op_lin, & + u_obs_op_adj, u_init_dim_obs_f, u_obs_op_f, u_init_obs_f, u_init_obs_l, & + u_prodrinva_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + u_prepoststep, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble var) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs_f + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_f + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs_f + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + init_dim_obs_f_pdaf_c_ptr => u_init_dim_obs_f + obs_op_f_pdaf_c_ptr => u_obs_op_f + init_obs_f_pdaf_c_ptr => u_init_obs_f + init_obs_l_pdaf_c_ptr => u_init_obs_l + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAF_assim_offline_en3dvar_lestkf(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, & + f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, & + f__init_obs_f_pdaf, & + f__init_obs_l_pdaf, f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, f__l2g_state_pdaf, & + f__g2l_obs_pdaf, f__init_obsvar_pdaf, & + f__init_obsvar_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF_assim_offline_en3dvar_lestkf + + SUBROUTINE c__PDAF_assimilate_ensrf(u_collect_state, u_distribute_state, & + u_init_dim_obs, u_obs_op, u_init_obs, u_init_obsvars, & + u_localize_covar_serial, u_prepoststep, u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Initialize vector of observation error variances + procedure(c__init_obsvars_pdaf) :: u_init_obsvars + ! Apply localization for single-observation vectors + procedure(c__localize_covar_serial_pdaf) :: u_localize_covar_serial + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obsvars_pdaf_c_ptr => u_init_obsvars + localize_covar_serial_pdaf_c_ptr => u_localize_covar_serial + prepoststep_pdaf_c_ptr => u_prepoststep + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_assimilate_ensrf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__init_obsvars_pdaf, & + f__localize_covar_serial_pdaf, f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_assimilate_ensrf + + SUBROUTINE c__PDAF_assim_offline_ensrf(u_init_dim_obs, u_obs_op, u_init_obs, & + u_init_obsvars, u_localize_covar_serial, u_prepoststep, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Initialize vector of observation error variances + procedure(c__init_obsvars_pdaf) :: u_init_obsvars + ! Apply localization for single-observation vectors + procedure(c__localize_covar_serial_pdaf) :: u_localize_covar_serial + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obsvars_pdaf_c_ptr => u_init_obsvars + localize_covar_serial_pdaf_c_ptr => u_localize_covar_serial + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAF_assim_offline_ensrf(f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, & + f__init_obsvars_pdaf, f__localize_covar_serial_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF_assim_offline_ensrf + + SUBROUTINE c__PDAF_assimilate_lknetf(u_collect_state, u_distribute_state, & + u_init_dim_obs, u_obs_op, u_init_obs, u_init_obs_l, u_prepoststep, & + u_prodrinva_l, u_prodrinva_hyb_l, u_init_n_domains_p, u_init_dim_l, & + u_init_dim_obs_l, u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, & + u_init_obsvar_l, u_likelihood_l, u_likelihood_hyb_l, u_next_observation, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide product R^-1 A on local analysis domain with hybrid weight + procedure(c__prodrinva_hyb_l_pdaf) :: u_prodrinva_hyb_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! Compute likelihood + procedure(c__likelihood_l_pdaf) :: u_likelihood_l + ! Compute likelihood with hybrid weight + procedure(c__likelihood_hyb_l_pdaf) :: u_likelihood_hyb_l + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + prodrinva_hyb_l_pdaf_c_ptr => u_prodrinva_hyb_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + likelihood_l_pdaf_c_ptr => u_likelihood_l + likelihood_hyb_l_pdaf_c_ptr => u_likelihood_hyb_l + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_assimilate_lknetf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__init_obs_l_pdaf, f__prepoststep_pdaf, & + f__prodrinva_l_pdaf, f__prodrinva_hyb_l_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, f__l2g_state_pdaf, f__g2l_obs_pdaf, f__init_obsvar_pdaf, & + f__init_obsvar_l_pdaf, f__likelihood_l_pdaf, f__likelihood_hyb_l_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_assimilate_lknetf + + SUBROUTINE c__PDAF_assim_offline_lknetf(u_init_dim_obs, u_obs_op, & + u_init_obs, u_init_obs_l, u_prepoststep, u_prodrinva_l, & + u_prodrinva_hyb_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + u_likelihood_l, u_likelihood_hyb_l, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide product R^-1 A on local analysis domain with hybrid weight + procedure(c__prodrinva_hyb_l_pdaf) :: u_prodrinva_hyb_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! Compute likelihood + procedure(c__likelihood_l_pdaf) :: u_likelihood_l + ! Compute likelihood with hybrid weight + procedure(c__likelihood_hyb_l_pdaf) :: u_likelihood_hyb_l + + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + prodrinva_hyb_l_pdaf_c_ptr => u_prodrinva_hyb_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + likelihood_l_pdaf_c_ptr => u_likelihood_l + likelihood_hyb_l_pdaf_c_ptr => u_likelihood_hyb_l + + call PDAF_assim_offline_lknetf(f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, & + f__init_obs_l_pdaf, f__prepoststep_pdaf, f__prodrinva_l_pdaf, f__prodrinva_hyb_l_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, & + f__l2g_state_pdaf, f__g2l_obs_pdaf, f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, & + f__likelihood_l_pdaf, f__likelihood_hyb_l_pdaf, outflag) + + END SUBROUTINE c__PDAF_assim_offline_lknetf + + SUBROUTINE c__PDAF_assimilate_hyb3dvar_estkf(u_collect_state, & + u_distribute_state, u_init_dim_obs, u_obs_op, u_init_obs, u_prodrinva, & + u_cvt_ens, u_cvt_adj_ens, u_cvt, u_cvt_adj, u_obs_op_lin, u_obs_op_adj, & + u_init_obsvar, u_prepoststep, u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble var) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + init_obsvar_pdaf_c_ptr => u_init_obsvar + prepoststep_pdaf_c_ptr => u_prepoststep + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_assimilate_hyb3dvar_estkf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__init_obsvar_pdaf, f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_assimilate_hyb3dvar_estkf + + SUBROUTINE c__PDAF_assim_offline_hyb3dvar_estkf(u_init_dim_obs, u_obs_op, & + u_init_obs, u_prodrinva, u_cvt, u_cvt_adj, u_cvt_ens, u_cvt_adj_ens, & + u_obs_op_lin, u_obs_op_adj, u_init_obsvar, u_prepoststep, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Apply control vector transform matrix (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble var) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + init_obsvar_pdaf_c_ptr => u_init_obsvar + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAF_assim_offline_hyb3dvar_estkf(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__prodrinva_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__init_obsvar_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF_assim_offline_hyb3dvar_estkf + + SUBROUTINE c__PDAF_assimilate_hyb3dvar_lestkf(u_collect_state, & + u_distribute_state, u_init_dim_obs, u_obs_op, u_init_obs, u_prodrinva, & + u_cvt_ens, u_cvt_adj_ens, u_cvt, u_cvt_adj, u_obs_op_lin, u_obs_op_adj, & + u_init_dim_obs_f, u_obs_op_f, u_init_obs_f, u_init_obs_l, u_prodrinva_l, & + u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, u_g2l_state, & + u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, u_prepoststep, & + u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble var) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs_f + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_f + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs_f + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + init_dim_obs_f_pdaf_c_ptr => u_init_dim_obs_f + obs_op_f_pdaf_c_ptr => u_obs_op_f + init_obs_f_pdaf_c_ptr => u_init_obs_f + init_obs_l_pdaf_c_ptr => u_init_obs_l + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + prepoststep_pdaf_c_ptr => u_prepoststep + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_assimilate_hyb3dvar_lestkf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, f__init_obs_f_pdaf, f__init_obs_l_pdaf, & + f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__g2l_state_pdaf, f__l2g_state_pdaf, f__g2l_obs_pdaf, f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, & + f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_assimilate_hyb3dvar_lestkf + + SUBROUTINE c__PDAF_assim_offline_hyb3dvar_lestkf(u_init_dim_obs, u_obs_op, & + u_init_obs, u_prodrinva, u_cvt_ens, u_cvt_adj_ens, u_cvt, u_cvt_adj, & + u_obs_op_lin, u_obs_op_adj, u_init_dim_obs_f, u_obs_op_f, u_init_obs_f, & + u_init_obs_l, u_prodrinva_l, u_init_n_domains_p, u_init_dim_l, & + u_init_dim_obs_l, u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, & + u_init_obsvar_l, u_prepoststep, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble var) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs_f + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_f + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs_f + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + init_dim_obs_f_pdaf_c_ptr => u_init_dim_obs_f + obs_op_f_pdaf_c_ptr => u_obs_op_f + init_obs_f_pdaf_c_ptr => u_init_obs_f + init_obs_l_pdaf_c_ptr => u_init_obs_l + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAF_assim_offline_hyb3dvar_lestkf(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, & + f__init_obs_f_pdaf, f__init_obs_l_pdaf, f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, f__l2g_state_pdaf, f__g2l_obs_pdaf, & + f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF_assim_offline_hyb3dvar_lestkf + + SUBROUTINE c__PDAF_assimilate_lestkf(u_collect_state, u_distribute_state, & + u_init_dim_obs, u_obs_op, u_init_obs, u_init_obs_l, u_prepoststep, & + u_prodrinva_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_assimilate_lestkf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__init_obs_l_pdaf, f__prepoststep_pdaf, & + f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__g2l_state_pdaf, f__l2g_state_pdaf, f__g2l_obs_pdaf, f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_assimilate_lestkf + + SUBROUTINE c__PDAF_assim_offline_lestkf(u_init_dim_obs, u_obs_op, & + u_init_obs, u_init_obs_l, u_prepoststep, u_prodrinva_l, & + u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, u_g2l_state, & + u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + + call PDAF_assim_offline_lestkf(f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, & + f__init_obs_l_pdaf, f__prepoststep_pdaf, f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, f__l2g_state_pdaf, f__g2l_obs_pdaf, & + f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, outflag) + + END SUBROUTINE c__PDAF_assim_offline_lestkf + + SUBROUTINE c__PDAF_assimilate_enkf(u_collect_state, u_distribute_state, & + u_init_dim_obs, u_obs_op, u_init_obs, u_prepoststep, u_add_obs_error, & + u_init_obs_covar, u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Add obs error covariance R to HPH in EnKF + procedure(c__add_obs_err_pdaf) :: u_add_obs_error + ! Initialize obs. error cov. matrix R in EnKF + procedure(c__init_obs_covar_pdaf) :: u_init_obs_covar + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + add_obs_err_pdaf_c_ptr => u_add_obs_error + init_obs_covar_pdaf_c_ptr => u_init_obs_covar + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_assimilate_enkf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__prepoststep_pdaf, f__add_obs_err_pdaf, & + f__init_obs_covar_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_assimilate_enkf + + SUBROUTINE c__PDAF_assim_offline_enkf(u_init_dim_obs, u_obs_op, u_init_obs, & + u_prepoststep, u_add_obs_err, u_init_obs_covar, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Add obs error covariance R to HPH in EnKF + procedure(c__add_obs_err_pdaf) :: u_add_obs_err + ! Initialize obs. error cov. matrix R in EnKF + procedure(c__init_obs_covar_pdaf) :: u_init_obs_covar + + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + add_obs_err_pdaf_c_ptr => u_add_obs_err + init_obs_covar_pdaf_c_ptr => u_init_obs_covar + + call PDAF_assim_offline_enkf(f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, & + f__prepoststep_pdaf, f__add_obs_err_pdaf, f__init_obs_covar_pdaf, outflag) + + END SUBROUTINE c__PDAF_assim_offline_enkf + + SUBROUTINE c__PDAF_assimilate_letkf(u_collect_state, u_distribute_state, & + u_init_dim_obs, u_obs_op, u_init_obs, u_init_obs_l, u_prepoststep, & + u_prodrinva_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_assimilate_letkf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__init_obs_l_pdaf, f__prepoststep_pdaf, & + f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__g2l_state_pdaf, f__l2g_state_pdaf, f__g2l_obs_pdaf, f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_assimilate_letkf + + SUBROUTINE c__PDAF_assim_offline_letkf(u_init_dim_obs, u_obs_op, u_init_obs, & + u_init_obs_l, u_prepoststep, u_prodrinva_l, u_init_n_domains_p, & + u_init_dim_l, u_init_dim_obs_l, u_g2l_state, u_l2g_state, u_g2l_obs, & + u_init_obsvar, u_init_obsvar_l, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + + call PDAF_assim_offline_letkf(f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, & + f__init_obs_l_pdaf, f__prepoststep_pdaf, f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, f__l2g_state_pdaf, f__g2l_obs_pdaf, & + f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, outflag) + + END SUBROUTINE c__PDAF_assim_offline_letkf + + SUBROUTINE c__PDAF_assimilate_seik(u_collect_state, u_distribute_state, & + u_init_dim_obs, u_obs_op, u_init_obs, u_prepoststep, u_prodrinva, & + u_init_obsvar, u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_pdaf_c_ptr => u_prodrinva + init_obsvar_pdaf_c_ptr => u_init_obsvar + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_assimilate_seik(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__prepoststep_pdaf, f__prodrinva_pdaf, & + f__init_obsvar_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_assimilate_seik + + SUBROUTINE c__PDAF_assim_offline_seik(u_init_dim_obs, u_obs_op, u_init_obs, & + u_prepoststep, u_prodrinva, u_init_obsvar, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_pdaf_c_ptr => u_prodrinva + init_obsvar_pdaf_c_ptr => u_init_obsvar + + call PDAF_assim_offline_seik(f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, & + f__prepoststep_pdaf, f__prodrinva_pdaf, f__init_obsvar_pdaf, outflag) + + END SUBROUTINE c__PDAF_assim_offline_seik + + SUBROUTINE c__PDAF_assimilate_lnetf(u_collect_state, u_distribute_state, & + u_init_dim_obs, u_obs_op, u_init_obs, u_init_obs_l, u_prepoststep, & + u_likelihood_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Compute observation likelihood for an ensemble member + procedure(c__likelihood_l_pdaf) :: u_likelihood_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + likelihood_l_pdaf_c_ptr => u_likelihood_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_assimilate_lnetf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__init_obs_l_pdaf, f__prepoststep_pdaf, & + f__likelihood_l_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__g2l_state_pdaf, f__l2g_state_pdaf, f__g2l_obs_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_assimilate_lnetf + + SUBROUTINE c__PDAF_assim_offline_lnetf(u_init_dim_obs, u_obs_op, u_init_obs, & + u_init_obs_l, u_prepoststep, u_likelihood_l, u_init_n_domains_p, & + u_init_dim_l, u_init_dim_obs_l, u_g2l_state, u_l2g_state, u_g2l_obs, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Compute observation likelihood for an ensemble member + procedure(c__likelihood_l_pdaf) :: u_likelihood_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + likelihood_l_pdaf_c_ptr => u_likelihood_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + + call PDAF_assim_offline_lnetf(f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, & + f__init_obs_l_pdaf, f__prepoststep_pdaf, f__likelihood_l_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, f__l2g_state_pdaf, f__g2l_obs_pdaf, & + outflag) + + END SUBROUTINE c__PDAF_assim_offline_lnetf + + SUBROUTINE c__PDAF_assimilate_prepost(u_collect_state, u_distribute_state, & + u_prepoststep, u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + prepoststep_pdaf_c_ptr => u_prepoststep + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_assimilate_prepost(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_assimilate_prepost + + SUBROUTINE c__PDAF_assimilate_en3dvar_estkf(u_collect_state, & + u_distribute_state, u_init_dim_obs, u_obs_op, u_init_obs, u_prodrinva, & + u_cvt_ens, u_cvt_adj_ens, u_obs_op_lin, u_obs_op_adj, u_init_obsvar, & + u_prepoststep, u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble var) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + init_obsvar_pdaf_c_ptr => u_init_obsvar + prepoststep_pdaf_c_ptr => u_prepoststep + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_assimilate_en3dvar_estkf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__init_obsvar_pdaf, & + f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_assimilate_en3dvar_estkf + + SUBROUTINE c__PDAF_assim_offline_en3dvar_estkf(u_init_dim_obs, u_obs_op, & + u_init_obs, u_prodrinva, u_cvt_ens, u_cvt_adj_ens, u_obs_op_lin, & + u_obs_op_adj, u_init_obsvar, u_prepoststep, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble var) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + init_obsvar_pdaf_c_ptr => u_init_obsvar + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAF_assim_offline_en3dvar_estkf(f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, f__init_obsvar_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF_assim_offline_en3dvar_estkf + + SUBROUTINE c__PDAF_assimilate_netf(u_collect_state, u_distribute_state, & + u_init_dim_obs, u_obs_op, u_init_obs, u_prepoststep, u_likelihood, & + u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Init. observation vector on local analysis domain + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Compute observation likelihood for an ensemble member + procedure(c__likelihood_pdaf) :: u_likelihood + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + likelihood_pdaf_c_ptr => u_likelihood + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_assimilate_netf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__prepoststep_pdaf, f__likelihood_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_assimilate_netf + + SUBROUTINE c__PDAF_assim_offline_netf(u_init_dim_obs, u_obs_op, u_init_obs, & + u_prepoststep, u_likelihood, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Init. observation vector on local analysis domain + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Compute observation likelihood for an ensemble member + procedure(c__likelihood_pdaf) :: u_likelihood + + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + likelihood_pdaf_c_ptr => u_likelihood + + call PDAF_assim_offline_netf(f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, & + f__prepoststep_pdaf, f__likelihood_pdaf, outflag) + + END SUBROUTINE c__PDAF_assim_offline_netf + + SUBROUTINE c__PDAF_assimilate_pf(u_collect_state, u_distribute_state, & + u_init_dim_obs, u_obs_op, u_init_obs, u_prepoststep, u_likelihood, & + u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Init. observation vector on local analysis domain + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Compute observation likelihood for an ensemble member + procedure(c__likelihood_pdaf) :: u_likelihood + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + likelihood_pdaf_c_ptr => u_likelihood + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_assimilate_pf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__prepoststep_pdaf, f__likelihood_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_assimilate_pf + + SUBROUTINE c__PDAF_assim_offline_pf(u_init_dim_obs, u_obs_op, u_init_obs, & + u_prepoststep, u_likelihood, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Init. observation vector on local analysis domain + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Compute observation likelihood for an ensemble member + procedure(c__likelihood_pdaf) :: u_likelihood + + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + likelihood_pdaf_c_ptr => u_likelihood + + call PDAF_assim_offline_pf(f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, & + f__prepoststep_pdaf, f__likelihood_pdaf, outflag) + + END SUBROUTINE c__PDAF_assim_offline_pf + + SUBROUTINE c__PDAF_assimilate_lenkf(u_collect_state, u_distribute_state, & + u_init_dim_obs, u_obs_op, u_init_obs, u_prepoststep, u_localize, & + u_add_obs_error, u_init_obs_covar, u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Apply localization to HP and HPH^T + procedure(c__localize_covar_pdaf) :: u_localize + ! Add obs error covariance R to HPH in EnKF + procedure(c__add_obs_err_pdaf) :: u_add_obs_error + ! Initialize obs. error cov. matrix R in EnKF + procedure(c__init_obs_covar_pdaf) :: u_init_obs_covar + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + localize_covar_pdaf_c_ptr => u_localize + add_obs_err_pdaf_c_ptr => u_add_obs_error + init_obs_covar_pdaf_c_ptr => u_init_obs_covar + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_assimilate_lenkf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__prepoststep_pdaf, f__localize_covar_pdaf, & + f__add_obs_err_pdaf, f__init_obs_covar_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_assimilate_lenkf + + SUBROUTINE c__PDAF_assim_offline_lenkf(u_init_dim_obs, u_obs_op, u_init_obs, & + u_prepoststep, u_localize, u_add_obs_err, u_init_obs_covar, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Apply localization to HP and HPH^T + procedure(c__localize_covar_pdaf) :: u_localize + ! Add obs error covariance R to HPH in EnKF + procedure(c__add_obs_err_pdaf) :: u_add_obs_err + ! Initialize obs. error cov. matrix R in EnKF + procedure(c__init_obs_covar_pdaf) :: u_init_obs_covar + + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + localize_covar_pdaf_c_ptr => u_localize + add_obs_err_pdaf_c_ptr => u_add_obs_err + init_obs_covar_pdaf_c_ptr => u_init_obs_covar + + call PDAF_assim_offline_lenkf(f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, & + f__prepoststep_pdaf, f__localize_covar_pdaf, f__add_obs_err_pdaf, f__init_obs_covar_pdaf, outflag) + + END SUBROUTINE c__PDAF_assim_offline_lenkf + + SUBROUTINE c__PDAF_assimilate_etkf(u_collect_state, u_distribute_state, & + u_init_dim_obs, u_obs_op, u_init_obs, u_prepoststep, u_prodrinva, & + u_init_obsvar, u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_pdaf_c_ptr => u_prodrinva + init_obsvar_pdaf_c_ptr => u_init_obsvar + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_assimilate_etkf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__prepoststep_pdaf, f__prodrinva_pdaf, & + f__init_obsvar_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_assimilate_etkf + + SUBROUTINE c__PDAF_assim_offline_etkf(u_init_dim_obs, u_obs_op, u_init_obs, & + u_prepoststep, u_prodrinva, u_init_obsvar, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_pdaf_c_ptr => u_prodrinva + init_obsvar_pdaf_c_ptr => u_init_obsvar + + call PDAF_assim_offline_etkf(f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, & + f__prepoststep_pdaf, f__prodrinva_pdaf, f__init_obsvar_pdaf, outflag) + + END SUBROUTINE c__PDAF_assim_offline_etkf + + SUBROUTINE c__PDAF_assimilate_lseik(u_collect_state, u_distribute_state, & + u_init_dim_obs, u_obs_op, u_init_obs, u_init_obs_l, u_prepoststep, & + u_prodrinva_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_assimilate_lseik(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__init_obs_l_pdaf, f__prepoststep_pdaf, & + f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__g2l_state_pdaf, f__l2g_state_pdaf, f__g2l_obs_pdaf, f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_assimilate_lseik + + SUBROUTINE c__PDAF_assim_offline_lseik(u_init_dim_obs, u_obs_op, u_init_obs, & + u_init_obs_l, u_prepoststep, u_prodrinva_l, u_init_n_domains_p, & + u_init_dim_l, u_init_dim_obs_l, u_g2l_state, u_l2g_state, u_g2l_obs, & + u_init_obsvar, u_init_obsvar_l, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + + call PDAF_assim_offline_lseik(f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, & + f__init_obs_l_pdaf, f__prepoststep_pdaf, f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, f__l2g_state_pdaf, f__g2l_obs_pdaf, & + f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, outflag) + + END SUBROUTINE c__PDAF_assim_offline_lseik + + SUBROUTINE c__PDAF_generate_obs(u_collect_state, u_distribute_state, & + u_init_dim_obs_f, u_obs_op_f, u_init_obserr_f, u_get_obs_f, & + u_prepoststep, u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs_f + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_f + ! Initialize vector of observation error standard deviations + procedure(c__init_obserr_f_pdaf) :: u_init_obserr_f + ! Provide observation vector to user + procedure(c__get_obs_f_pdaf) :: u_get_obs_f + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Routine to provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_f_pdaf_c_ptr => u_init_dim_obs_f + obs_op_f_pdaf_c_ptr => u_obs_op_f + init_obserr_f_pdaf_c_ptr => u_init_obserr_f + get_obs_f_pdaf_c_ptr => u_get_obs_f + prepoststep_pdaf_c_ptr => u_prepoststep + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_generate_obs(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, f__init_obserr_f_pdaf, f__get_obs_f_pdaf, & + f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_generate_obs + + SUBROUTINE c__PDAF_generate_obs_offline(u_init_dim_obs_f, u_obs_op_f, & + u_init_obserr_f, u_get_obs_f, u_prepoststep, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs_f + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_f + ! Initialize vector of observation error standard deviations + procedure(c__init_obserr_f_pdaf) :: u_init_obserr_f + ! Provide observation vector + procedure(c__get_obs_f_pdaf) :: u_get_obs_f + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + init_dim_obs_f_pdaf_c_ptr => u_init_dim_obs_f + obs_op_f_pdaf_c_ptr => u_obs_op_f + init_obserr_f_pdaf_c_ptr => u_init_obserr_f + get_obs_f_pdaf_c_ptr => u_get_obs_f + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAF_generate_obs_offline(f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, & + f__init_obserr_f_pdaf, f__get_obs_f_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF_generate_obs_offline +END MODULE pdaf_c_assim diff --git a/pyPDAF/source/src/fortran/pdaf_c_callback.f90 b/pyPDAF/source/src/fortran/pdaf_c_callback.f90 new file mode 100644 index 0000000000000000000000000000000000000000..956c22228f7bc89ebad20b6c0408457e012fe06e --- /dev/null +++ b/pyPDAF/source/src/fortran/pdaf_c_callback.f90 @@ -0,0 +1,382 @@ +MODULE pdaf_c_callback +use iso_c_binding, only: c_int, c_double, c_bool +use PDAF + +implicit none + +contains + SUBROUTINE c__PDAFomi_init_obs_f_cb(step, dim_obs_f, observation_f) bind(c) + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Dimension of full observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_f + ! Full observation vector + REAL(c_double), DIMENSION(dim_obs_f), INTENT(out) :: observation_f + + + call PDAFomi_init_obs_f_cb(step, dim_obs_f, observation_f) + + END SUBROUTINE c__PDAFomi_init_obs_f_cb + + SUBROUTINE c__PDAFomi_init_obsvar_cb(step, dim_obs_p, obs_p, meanvar) bind(c) + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Mean observation error variance + REAL(c_double), INTENT(out) :: meanvar + + + call PDAFomi_init_obsvar_cb(step, dim_obs_p, obs_p, meanvar) + + END SUBROUTINE c__PDAFomi_init_obsvar_cb + + SUBROUTINE c__PDAFomi_init_obsvars_f_cb(step, dim_obs_f, var_f) bind(c) + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Dimension of full observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_f + ! vector of observation error variances + REAL(c_double), DIMENSION(dim_obs_f), INTENT(out) :: var_f + + + call PDAFomi_init_obsvars_f_cb(step, dim_obs_f, var_f) + + END SUBROUTINE c__PDAFomi_init_obsvars_f_cb + + SUBROUTINE c__PDAFomi_g2l_obs_cb(domain_p, step, dim_obs_f, dim_obs_l, & + ostate_f, ostate_l) bind(c) + ! Index of current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Dimension of full PE-local observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_f + ! Dimension of local observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Full PE-local obs.ervation vector + REAL(c_double), DIMENSION(dim_obs_f), INTENT(in) :: ostate_f + ! Observation vector on local domain + REAL(c_double), DIMENSION(dim_obs_l), INTENT(out) :: ostate_l + + + call PDAFomi_g2l_obs_cb(domain_p, step, dim_obs_f, dim_obs_l, ostate_f, & + ostate_l) + + END SUBROUTINE c__PDAFomi_g2l_obs_cb + + SUBROUTINE c__PDAFomi_init_obs_l_cb(domain_p, step, dim_obs_l, & + observation_l) bind(c) + ! Index of current local analysis domain index + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Local observation vector + REAL(c_double), DIMENSION(dim_obs_l), INTENT(out) :: observation_l + + + call PDAFomi_init_obs_l_cb(domain_p, step, dim_obs_l, observation_l) + + END SUBROUTINE c__PDAFomi_init_obs_l_cb + + SUBROUTINE c__PDAFomi_init_obsvar_l_cb(domain_p, step, dim_obs_l, obs_l, & + meanvar_l) bind(c) + ! Index of current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Local observation vector + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: obs_l + ! Mean local observation error variance + REAL(c_double), INTENT(out) :: meanvar_l + + + call PDAFomi_init_obsvar_l_cb(domain_p, step, dim_obs_l, obs_l, meanvar_l) + + END SUBROUTINE c__PDAFomi_init_obsvar_l_cb + + SUBROUTINE c__PDAFomi_prodRinvA_l_cb(domain_p, step, dim_obs_l, rank, obs_l, & + a_l, c_l) bind(c) + ! Index of current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Dimension of local observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: rank + ! Local vector of observations + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: obs_l + ! Input matrix + REAL(c_double), DIMENSION(dim_obs_l, rank), INTENT(inout) :: a_l + ! Output matrix + REAL(c_double), DIMENSION(dim_obs_l, rank), INTENT(out) :: c_l + + + call PDAFomi_prodRinvA_l_cb(domain_p, step, dim_obs_l, rank, obs_l, a_l, c_l) + + END SUBROUTINE c__PDAFomi_prodRinvA_l_cb + + SUBROUTINE c__PDAFomi_likelihood_l_cb(domain_p, step, dim_obs_l, obs_l, & + resid_l, lhood_l) bind(c) + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of obs. vector + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! PE-local vector of observations + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: obs_l + ! Input vector of residuum + REAL(c_double), DIMENSION(dim_obs_l), INTENT(inout) :: resid_l + ! Output vector - log likelihood + REAL(c_double), INTENT(out) :: lhood_l + + + call PDAFomi_likelihood_l_cb(domain_p, step, dim_obs_l, obs_l, resid_l, & + lhood_l) + + END SUBROUTINE c__PDAFomi_likelihood_l_cb + + SUBROUTINE c__PDAFomi_prodRinvA_hyb_l_cb(domain_p, step, dim_obs_l, rank, & + obs_l, alpha, a_l, c_l) bind(c) + ! Index of current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Dimension of local observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: rank + ! Local vector of observations + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: obs_l + ! Hybrid weight + REAL(c_double), INTENT(in) :: alpha + ! Input matrix + REAL(c_double), DIMENSION(dim_obs_l, rank), INTENT(inout) :: a_l + ! Output matrix + REAL(c_double), DIMENSION(dim_obs_l, rank), INTENT(out) :: c_l + + + call PDAFomi_prodRinvA_hyb_l_cb(domain_p, step, dim_obs_l, rank, obs_l, & + alpha, a_l, c_l) + + END SUBROUTINE c__PDAFomi_prodRinvA_hyb_l_cb + + SUBROUTINE c__PDAFomi_likelihood_hyb_l_cb(domain_p, step, dim_obs_l, obs_l, & + resid_l, alpha, lhood_l) bind(c) + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of obs. vector + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! PE-local vector of observations + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: obs_l + ! Input vector of residuum + REAL(c_double), DIMENSION(dim_obs_l), INTENT(inout) :: resid_l + ! Hybrid weight + REAL(c_double), INTENT(in) :: alpha + ! Output vector - log likelihood + REAL(c_double), INTENT(out) :: lhood_l + + + call PDAFomi_likelihood_hyb_l_cb(domain_p, step, dim_obs_l, obs_l, & + resid_l, alpha, lhood_l) + + END SUBROUTINE c__PDAFomi_likelihood_hyb_l_cb + + SUBROUTINE c__PDAFomi_prodRinvA_cb(step, dim_obs_p, ncol, obs_p, a_p, & + c_p) bind(c) + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Dimension of PE-local observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Number of columns in A_p and C_p + INTEGER(c_int), INTENT(in) :: ncol + ! PE-local vector of observations + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Input matrix + REAL(c_double), DIMENSION(dim_obs_p, ncol), INTENT(in) :: a_p + ! Output matrix + REAL(c_double), DIMENSION(dim_obs_p, ncol), INTENT(out) :: c_p + + + call PDAFomi_prodRinvA_cb(step, dim_obs_p, ncol, obs_p, a_p, c_p) + + END SUBROUTINE c__PDAFomi_prodRinvA_cb + + SUBROUTINE c__PDAFomi_likelihood_cb(step, dim_obs, obs, resid, lhood) bind(c) + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of obs. vector + INTEGER(c_int), INTENT(in) :: dim_obs + ! PE-local vector of observations + REAL(c_double), DIMENSION(dim_obs), INTENT(in) :: obs + ! Input vector of residuum + REAL(c_double), DIMENSION(dim_obs), INTENT(in) :: resid + ! Output vector - log likelihood + REAL(c_double), INTENT(out) :: lhood + + + call PDAFomi_likelihood_cb(step, dim_obs, obs, resid, lhood) + + END SUBROUTINE c__PDAFomi_likelihood_cb + + SUBROUTINE c__PDAFomi_add_obs_error_cb(step, dim_obs_p, c_p) bind(c) + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Dimension of PE-local observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Matrix to which R is added + REAL(c_double), DIMENSION(dim_obs_p,dim_obs_p), INTENT(inout) :: c_p + + + call PDAFomi_add_obs_error_cb(step, dim_obs_p, c_p) + + END SUBROUTINE c__PDAFomi_add_obs_error_cb + + SUBROUTINE c__PDAFomi_init_obscovar_cb(step, dim_obs, dim_obs_p, covar, & + m_state_p, isdiag) bind(c) + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs + ! PE-local dimension of obs. vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Observation error covar. matrix + REAL(c_double), DIMENSION(dim_obs,dim_obs), INTENT(out) :: covar + ! Observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: m_state_p + ! Whether matrix R is diagonal + LOGICAL(c_bool), INTENT(out) :: isdiag + + + call PDAFomi_init_obscovar_cb(step, dim_obs, dim_obs_p, covar, m_state_p, & + isdiag) + + END SUBROUTINE c__PDAFomi_init_obscovar_cb + + SUBROUTINE c__PDAFomi_init_obserr_f_cb(step, dim_obs_f, obs_f, obserr_f) bind(c) + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Full dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_f + ! Full observation vector + REAL(c_double), DIMENSION(dim_obs_f), INTENT(in) :: obs_f + ! Full observation error stddev + REAL(c_double), DIMENSION(dim_obs_f), INTENT(out) :: obserr_f + + + call PDAFomi_init_obserr_f_cb(step, dim_obs_f, obs_f, obserr_f) + + END SUBROUTINE c__PDAFomi_init_obserr_f_cb + + SUBROUTINE c__PDAFomi_localize_covar_cb(dim_p, dim_obs, hp_p, hph) bind(c) + ! Process-local state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! Number of observations + INTEGER(c_int), INTENT(in) :: dim_obs + ! Process-local part of matrix HP + REAL(c_double), DIMENSION(dim_obs, dim_p), INTENT(inout) :: hp_p + ! Matrix HPH + REAL(c_double), DIMENSION(dim_obs, dim_obs), INTENT(inout) :: hph + + + call PDAFomi_localize_covar_cb(dim_p, dim_obs, hp_p, hph) + + END SUBROUTINE c__PDAFomi_localize_covar_cb + + SUBROUTINE c__PDAFomi_localize_covar_serial_cb(iobs, dim_p, dim_obs, hp_p, & + hxy_p) bind(c) + ! Index of current observation + INTEGER(c_int), INTENT(in) :: iobs + ! Process-local state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! Number of observations + INTEGER(c_int), INTENT(in) :: dim_obs + ! Process-local part of matrix HP for observation iobs + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: hp_p + ! Process-local part of matrix HX(HX_all) for full observations + REAL(c_double), DIMENSION(dim_obs), INTENT(inout) :: hxy_p + + + call PDAFomi_localize_covar_serial_cb(iobs, dim_p, dim_obs, hp_p, hxy_p) + + END SUBROUTINE c__PDAFomi_localize_covar_serial_cb + + SUBROUTINE c__PDAFomi_omit_by_inno_l_cb(domain_p, dim_obs_l, resid_l, & + obs_l) bind(c) + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! PE-local dimension of obs. vector + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Input vector of residuum + REAL(c_double), DIMENSION(dim_obs_l), INTENT(inout) :: resid_l + ! Input vector of local observations + REAL(c_double), DIMENSION(dim_obs_l), INTENT(inout) :: obs_l + + + call PDAFomi_omit_by_inno_l_cb(domain_p, dim_obs_l, resid_l, obs_l) + + END SUBROUTINE c__PDAFomi_omit_by_inno_l_cb + + SUBROUTINE c__PDAFomi_omit_by_inno_cb(dim_obs_f, resid_f, obs_f) bind(c) + ! Full dimension of obs. vector + INTEGER(c_int), INTENT(in) :: dim_obs_f + ! Input vector of residuum + REAL(c_double), DIMENSION(dim_obs_f), INTENT(inout) :: resid_f + ! Input vector of full observations + REAL(c_double), DIMENSION(dim_obs_f), INTENT(inout) :: obs_f + + + call PDAFomi_omit_by_inno_cb(dim_obs_f, resid_f, obs_f) + + END SUBROUTINE c__PDAFomi_omit_by_inno_cb + + SUBROUTINE c__PDAFlocal_g2l_cb(step, domain_p, dim_p, state_p, dim_l, & + state_l) bind(c) + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! PE-local full state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local full state vector + REAL(c_double), DIMENSION(dim_p), INTENT(in) :: state_p + ! Local state dimension + INTEGER(c_int), INTENT(in) :: dim_l + ! State vector on local analysis domain + REAL(c_double), DIMENSION(dim_l), INTENT(out) :: state_l + + + call PDAFlocal_g2l_cb(step, domain_p, dim_p, state_p, dim_l, state_l) + + END SUBROUTINE c__PDAFlocal_g2l_cb + + SUBROUTINE c__PDAFlocal_l2g_cb(step, domain_p, dim_l, state_l, dim_p, & + state_p) bind(c) + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Local state dimension + INTEGER(c_int), INTENT(in) :: dim_l + ! State vector on local analysis domain + REAL(c_double), DIMENSION(dim_l), INTENT(in) :: state_l + ! PE-local full state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local full state vector + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + + + call PDAFlocal_l2g_cb(step, domain_p, dim_l, state_l, dim_p, state_p) + + END SUBROUTINE c__PDAFlocal_l2g_cb +END MODULE pdaf_c_callback diff --git a/pyPDAF/source/src/fortran/pdaf_c_cb_interface.f90 b/pyPDAF/source/src/fortran/pdaf_c_cb_interface.f90 new file mode 100644 index 0000000000000000000000000000000000000000..c83c21d75b786f7a34a1d0492d34f3f94d80e085 --- /dev/null +++ b/pyPDAF/source/src/fortran/pdaf_c_cb_interface.f90 @@ -0,0 +1,562 @@ +module pdaf_c_cb_interface +implicit none + +abstract interface + SUBROUTINE c__add_obs_err_pdaf(step, dim_obs_p, C_p) bind(c) + use iso_c_binding, only: c_double, c_int + IMPLICIT NONE + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Matrix to that observation covariance R is added + REAL(c_double), DIMENSION(dim_obs_p,dim_obs_p), INTENT(inout) :: C_p + END SUBROUTINE c__add_obs_err_pdaf + + SUBROUTINE c__init_ens_pdaf(filtertype, dim_p, dim_ens, state_p, uinv, ens_p, flag) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! filter type given in PDAF_init + integer(c_int), intent(in) :: filtertype + ! PE-local state dimension given by PDAF_init + integer(c_int), intent(in) :: dim_p + ! number of ensemble members + integer(c_int), intent(in) :: dim_ens + ! PE-local model state + ! This array must be filled with the initial + ! state of the model for SEEK, but it is not + ! used for ensemble-based filters. + ! + ! One can still make use of this array within + ! this function. + real(c_double), DIMENSION(dim_p), intent(inout) :: state_p + ! This array is the inverse of matrix + ! formed by right singular vectors of error + ! covariance matrix of ensemble perturbations. + ! + ! This array has to be filled in SEEK, but it is + ! not used for ensemble-based filters. + ! Nevertheless, one can still make use of this + ! array within this function e.g., + ! for generating an initial ensemble perturbation + ! from a given covariance matrix. + ! + ! Dimension of this array is determined by the + ! filter type. + ! + ! - (dim_ens, dim_ens) for (L)ETKF, (L)NETF, (L)KNETF, and SEEK + ! - (dim_ens - 1, dim_ens - 1) for (L)SEIK, (L)ESTKF, and 3DVar using ensemble + ! - (1, 1) for (L)EnKF, particle filters and gen_obs + real(c_double), DIMENSION(dim_ens - 1, dim_ens-1), intent(inout) :: uinv + ! PE-local ensemble + real(c_double), DIMENSION(dim_p, dim_ens), intent(inout) :: ens_p + ! pdaf status flag + integer(c_int), intent(inout) :: flag + end subroutine c__init_ens_pdaf + + subroutine c__next_observation_pdaf(stepnow, nsteps, doexit, time) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! the current time step given by PDAF + integer(c_int), intent(in) :: stepnow + ! number of forecast time steps until next assimilation; + ! this can also be interpreted as + ! number of assimilation function calls + ! to perform a new assimilation + integer(c_int), intent(out) :: nsteps + ! whether to exit forecasting (1 for exit) + integer(c_int), intent(out) :: doexit + ! current model (physical) time + real(c_double), intent(out) :: time + end subroutine c__next_observation_pdaf + + subroutine c__collect_state_pdaf(dim_p, state_p) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! pe-local state dimension + integer(c_int), intent(in) :: dim_p + ! local state vector + real(c_double), DIMENSION(dim_p), intent(inout) :: state_p + end subroutine c__collect_state_pdaf + + subroutine c__distribute_state_pdaf(dim_p, state_p) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! PE-local state dimension + integer(c_int), intent(in) :: dim_p + ! PE-local state vector + real(c_double), DIMENSION(dim_p), intent(inout) :: state_p + end subroutine c__distribute_state_pdaf + + subroutine c__prepoststep_pdaf(step, dim_p, dim_ens, dim_ens_l, & + dim_obs_p, state_p, uinv, ens_p, flag) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! current time step + ! (negative for call before analysis/preprocessing) + integer(c_int), intent(in) :: step + ! PE-local state vector dimension + integer(c_int), intent(in) :: dim_p + ! number of ensemble members + integer(c_int), intent(in) :: dim_ens + ! number of ensemble members run serially + ! on each model task + integer(c_int), intent(in) :: dim_ens_l + ! PE-local dimension of observation vector + integer(c_int), intent(in) :: dim_obs_p + ! pe-local forecast/analysis state + ! (the array 'state_p' is generally not + ! initialised in the case of ESTKF/ETKF/EnKF/SEIK, + ! so it can be used freely here.) + real(c_double), DIMENSION(dim_p), intent(inout) :: state_p + ! Inverse of the transformation matrix in ETKF and ESKTF; + ! inverse of matrix formed by right singular vectors of error + ! covariance matrix of ensemble perturbations in SEIK/SEEK. + ! not used in EnKF. + real(c_double), DIMENSION(dim_ens-1, dim_ens-1), intent(inout) :: uinv + ! PE-local ensemble + real(c_double), DIMENSION(dim_p, dim_ens), intent(inout) :: ens_p + ! pdaf status flag + integer(c_int), intent(in) :: flag + end subroutine c__prepoststep_pdaf + + subroutine c__init_dim_obs_pdaf(step, dim_obs_p) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! current time step + integer(c_int), intent(in) :: step + ! dimension of observation vector + integer(c_int), intent(out) :: dim_obs_p + end subroutine c__init_dim_obs_pdaf + + SUBROUTINE c__init_obs_pdaf(step, dim_obs_p, observation_p) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! Current time step + integer(c_int), intent(in) :: step + ! Size of the observation vector + integer(c_int), intent(in) :: dim_obs_p + ! Vector of observations + real(c_double), DIMENSION(dim_obs_p), intent(out) :: observation_p + END SUBROUTINE c__init_obs_pdaf + + SUBROUTINE c__init_obs_covar_pdaf(step, dim_obs, dim_obs_p, covar, obs_p, isdiag) bind(c) + use iso_c_binding, only: c_double, c_int, c_bool + implicit none + ! Current time step + integer(c_int), intent(in) :: step + ! Global size of observation vector + integer(c_int), intent(in) :: dim_obs + ! Size of process-local observation vector + integer(c_int), intent(in) :: dim_obs_p + ! Observation error covariance matrix + real(c_double), intent(out), dimension(dim_obs,dim_obs) :: covar + ! Process-local vector of observations + real(c_double), intent(in), dimension(dim_obs_p) :: obs_p + logical(c_bool), intent(out) :: isdiag + END SUBROUTINE c__init_obs_covar_pdaf + + SUBROUTINE c__init_obsvar_pdaf(step, dim_obs_p, obs_p, meanvar) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! Current time step + integer(c_int), intent(in) :: step + ! Size of observation vector + integer(c_int), intent(in) :: dim_obs_p + ! Vector of observations + real(c_double), intent(in), dimension(dim_obs_p) :: obs_p + ! Mean observation error variance + real(c_double), intent(out) :: meanvar + END SUBROUTINE c__init_obsvar_pdaf + + SUBROUTINE c__init_obsvars_pdaf(step, dim_obs_f, var_f) bind(c) + use iso_c_binding, only: c_double, c_int + IMPLICIT NONE + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Dimension of full observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_f + ! vector of observation error variances + REAL(c_double), DIMENSION(dim_obs_f), INTENT(out) :: var_f + END SUBROUTINE c__init_obsvars_pdaf + + SUBROUTINE c__prodRinvA_pdaf(step, dim_obs_p, rank, obs_p, A_p, C_p) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! Current time step + integer(c_int), intent(in) :: step + ! Number of observations at current time step (i.e. the size of the observation vector) + integer(c_int), intent(in) :: dim_obs_p + ! Number of the columns in the matrix processes here. + ! This is usually the ensemble size minus one + ! (or the rank of the initial covariance matrix) + integer(c_int), intent(in) :: rank + ! Vector of observations + real(c_double), intent(in), dimension(dim_obs_p) :: obs_p + ! Input matrix provided by PDAF + real(c_double), intent(in), dimension(dim_obs_p, rank) :: A_p + ! Output matrix + real(c_double), intent(out), dimension(dim_obs_p, rank) :: C_p + END SUBROUTINE c__prodRinvA_pdaf + + SUBROUTINE c__obs_op_pdaf(step, dim_p, dim_obs_p, state_p, m_state_p) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! Current time step + integer(c_int), intent(in) :: step + ! Size of state vector + ! (local part in case of parallel decomposed state) + integer(c_int), intent(in) :: dim_p + ! Size of PE-local observation vector + integer(c_int), intent(in) :: dim_obs_p + ! Model state vector + real(c_double), intent(in), dimension(dim_p) :: state_p + ! Observed state vector + ! (i.e. the result after applying the observation operator to state_p) + real(c_double), intent(inout), dimension(dim_obs_p) :: m_state_p + END SUBROUTINE c__obs_op_pdaf + + SUBROUTINE c__g2l_obs_pdaf(domain_p, step, dim_obs_f, dim_obs_l, mstate_f, mstate_l) bind(c) + use iso_c_binding, only: c_int + implicit none + ! Index of current local analysis domain + integer(c_int), intent(in) :: domain_p + ! Current time step + integer(c_int), intent(in) :: step + ! Size of full observation vector for model sub-domain + integer(c_int), intent(in) :: dim_obs_f + ! Size of observation vector for local analysis domain + integer(c_int), intent(in) :: dim_obs_l + ! Full observation vector for model sub-domain + integer(c_int), intent(in), dimension(dim_obs_f) :: mstate_f + ! Observation vector for local analysis domain + integer(c_int), intent(out), dimension(dim_obs_l) :: mstate_l + END SUBROUTINE c__g2l_obs_pdaf + + subroutine c__g2l_state_pdaf(step, domain_p, dim_p, state_p, dim_l, state_l) bind(c) + use iso_c_binding, only: c_int, c_double + implicit none + ! current time step + integer(c_int), intent(in) :: step + ! current local analysis domain + integer(c_int), intent(in) :: domain_p + ! pe-local full state dimension + integer(c_int), intent(in) :: dim_p + ! local state dimension + integer(c_int), intent(in) :: dim_l + ! pe-local full state vector + real(c_double), dimension(dim_p), intent(in) :: state_p + ! state vector on local analysis domain + real(c_double), dimension(dim_l), intent(out) :: state_l + end subroutine c__g2l_state_pdaf + + subroutine c__init_dim_l_pdaf(step, domain_p, dim_l) bind(c) + use iso_c_binding, only: c_int + implicit none + ! current time step + integer(c_int), intent(in) :: step + ! current local analysis domain + integer(c_int), intent(in) :: domain_p + ! local state dimension + integer(c_int), intent(out) :: dim_l + end subroutine c__init_dim_l_pdaf + + subroutine c__init_dim_obs_l_pdaf(domain_p, step, dim_obs_f, dim_obs_l) bind(c) + use iso_c_binding, only: c_int + implicit none + ! index of current local analysis domain + integer(c_int), intent(in) :: domain_p + ! current time step + integer(c_int), intent(in) :: step + ! full dimension of observation vector + integer(c_int), intent(in) :: dim_obs_f + ! local dimension of observation vector + integer(c_int), intent(out) :: dim_obs_l + end subroutine c__init_dim_obs_l_pdaf + + subroutine c__init_n_domains_p_pdaf(step, n_domains_p) bind(c) + use iso_c_binding, only: c_int + implicit none + ! current time step + integer(c_int), intent(in) :: step + ! pe-local number of analysis domains + integer(c_int), intent(out) :: n_domains_p + end subroutine c__init_n_domains_p_pdaf + + + SUBROUTINE c__init_obs_l_pdaf(domain_p, step, dim_obs_l, observation_l) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! Index of current local analysis domain + integer(c_int), intent(in) :: domain_p + ! Current time step + integer(c_int), intent(in) :: step + ! Local size of the observation vector + integer(c_int), intent(in) :: dim_obs_l + ! Local vector of observations + real(c_double), intent(out), dimension(dim_obs_l) :: observation_l + END SUBROUTINE c__init_obs_l_pdaf + + SUBROUTINE c__init_obsvar_l_pdaf(domain_p, step, dim_obs_l, obs_l, dim_obs_p, meanvar_l) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! Index of current local analysis domain + integer(c_int), intent(in) :: domain_p + ! Current time step + integer(c_int), intent(in) :: step + ! Local dimension of observation vector + integer(c_int), intent(in) :: dim_obs_l + ! Dimension of local observation vector + integer(c_int), intent(in) :: dim_obs_p + ! Local observation vector + real(c_double), intent(in), dimension(dim_obs_p) :: obs_l + ! Mean local observation error variance + real(c_double), intent(out) :: meanvar_l + END SUBROUTINE c__init_obsvar_l_pdaf + + SUBROUTINE c__init_obserr_f_pdaf(step, dim_obs_f, obs_f, obserr_f) bind(c) + use iso_c_binding, only: c_double, c_int + IMPLICIT NONE + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Full dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_f + ! Full observation vector + REAL(c_double), DIMENSION(dim_obs_f), INTENT(in) :: obs_f + ! Full observation error stddev + REAL(c_double), DIMENSION(dim_obs_f), INTENT(out) :: obserr_f + END SUBROUTINE c__init_obserr_f_pdaf + + subroutine c__l2g_state_pdaf(step, domain_p, dim_l, state_l, dim_p, state_p) bind(c) + use iso_c_binding, only: c_int, c_double + implicit none + ! current time step + integer(c_int), intent(in) :: step + ! current local analysis domain + integer(c_int), intent(in) :: domain_p + ! local state dimension + integer(c_int), intent(in) :: dim_l + ! pe-local full state dimension + integer(c_int), intent(in) :: dim_p + ! state vector on local analysis domain + real(c_double), DIMENSION(dim_l), intent(in) :: state_l + ! pe-local full state vector + real(c_double), DIMENSION(dim_p), intent(inout) :: state_p + end subroutine c__l2g_state_pdaf + + SUBROUTINE c__prodRinvA_l_pdaf(domain_p, step, dim_obs_l, rank, obs_l, A_l, C_l) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! Index of current local analysis domain + integer(c_int), intent(in) :: domain_p + ! Current time step + integer(c_int), intent(in) :: step + ! Number of local observations at current time step (i.e. the size of the local observation vector) + integer(c_int), intent(in) :: dim_obs_l + ! Number of the columns in the matrix processes here. + ! This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + integer(c_int), intent(in) :: rank + ! Local vector of observations + real(c_double), intent(in), dimension(dim_obs_l) :: obs_l + ! Input matrix provided by PDAF + real(c_double), intent(inout), dimension(dim_obs_l, rank) :: A_l + ! Output matrix + real(c_double), intent(out), dimension(dim_obs_l, rank) :: C_l + END SUBROUTINE c__prodRinvA_l_pdaf + + subroutine c__localize_covar_pdaf(dim_p, dim_obs, hp_p, hph) bind(c) + use iso_c_binding, only: c_int, c_double + implicit none + ! pe-local state dimension + integer(c_int), intent(in) :: dim_p + ! number of observations + integer(c_int), intent(in) :: dim_obs + ! pe local part of matrix hp + real(c_double), DIMENSION(dim_obs, dim_p), intent(inout) :: hp_p + ! matrix hph + real(c_double), DIMENSION(dim_obs, dim_obs), intent(inout) :: hph + end subroutine c__localize_covar_pdaf + + SUBROUTINE c__localize_covar_serial_pdaf(iobs, dim_p, dim_obs, HP_p, HXY_p) bind(c) + use iso_c_binding, only: c_int, c_double + IMPLICIT NONE + ! Index of current observation + INTEGER(c_int), INTENT(in) :: iobs + ! Process-local state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! Number of observations + INTEGER(c_int), INTENT(in) :: dim_obs + ! Process-local part of matrix HP for observation iobs + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: HP_p + ! Process-local part of matrix HX(HX_all) for full observations + REAL(c_double), DIMENSION(dim_obs), INTENT(inout) :: HXY_p + END SUBROUTINE c__localize_covar_serial_pdaf + + SUBROUTINE c__likelihood_pdaf(step, dim_obs_p, obs_p, resid, likely) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! Current time step + integer(c_int), intent(in) :: step + ! Number of observations at current time step (i.e. the size of the observation vector) + integer(c_int), intent(in) :: dim_obs_p + ! Vector of observations + real(c_double), intent(in), dimension(dim_obs_p) :: obs_p + ! Input vector holding the residual + real(c_double), intent(in), dimension(dim_obs_p) :: resid + ! Output value of the likelihood + real(c_double), intent(out) :: likely + END SUBROUTINE c__likelihood_pdaf + + SUBROUTINE c__likelihood_l_pdaf(domain_p, step, dim_obs_l, obs_l, resid_l, likely_l) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! Index of current local analysis domain + integer(c_int), intent(in) :: domain_p + ! Current time step + integer(c_int), intent(in) :: step + ! Number of local observations at current time step (i.e. the size of the local observation vector) + integer(c_int), intent(in) :: dim_obs_l + ! Local vector of observations + real(c_double), intent(in), dimension(dim_obs_l) :: obs_l + ! nput vector holding the local residual + real(c_double), intent(inout), dimension(dim_obs_l) :: resid_l + ! Output value of the local likelihood + real(c_double), intent(out) :: likely_l + END SUBROUTINE c__likelihood_l_pdaf + + SUBROUTINE c__get_obs_f_pdaf(step, dim_obs_f, observation_f) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! Current time step + integer(c_int), intent(in) :: step + ! Size of the full observation vector + integer(c_int), intent(in) :: dim_obs_f + ! Full vector of synthetic observations (process-local) + real(c_double), intent(in), dimension(dim_obs_f) :: observation_f + END SUBROUTINE c__get_obs_f_pdaf + + SUBROUTINE c__cvt_adj_ens_pdaf(iter, dim_p, dim_ens, dim_cv_ens_p, ens_p, Vcv_p, cv_p) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! Iteration of optimization + INTEGER(c_int), INTENT(in) :: iter + ! PE-local observation dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! Ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local dimension of control vector + INTEGER(c_int), INTENT(in) :: dim_cv_ens_p + ! PE-local ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(in) :: ens_p + ! PE-local input vector + REAL(c_double), DIMENSION(dim_p), INTENT(in) :: Vcv_p + ! PE-local result vector + REAL(c_double), DIMENSION(dim_cv_ens_p), INTENT(inout) :: cv_p + END SUBROUTINE c__cvt_adj_ens_pdaf + + SUBROUTINE c__cvt_adj_pdaf(iter, dim_p, dim_cvec, Vcv_p, cv_p) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! Iteration of optimization + INTEGER(c_int), INTENT(in) :: iter + ! PE-local observation dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! Dimension of control vector + INTEGER(c_int), INTENT(in) :: dim_cvec + ! PE-local result vector (state vector increment) + REAL(c_double), DIMENSION(dim_p), INTENT(in) :: Vcv_p + ! PE-local control vector + REAL(c_double), DIMENSION(dim_cvec), INTENT(inout) :: cv_p + END SUBROUTINE c__cvt_adj_pdaf + + SUBROUTINE c__cvt_pdaf(iter, dim_p, dim_cvec, cv_p, Vv_p) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! Iteration of optimization + INTEGER(c_int), INTENT(in) :: iter + ! PE-local observation dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! Dimension of control vector + INTEGER(c_int), INTENT(in) :: dim_cvec + ! PE-local control vector + REAL(c_double), DIMENSION(dim_cvec), INTENT(in) :: cv_p + ! PE-local result vector (state vector increment) + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: Vv_p + END SUBROUTINE c__cvt_pdaf + + SUBROUTINE c__cvt_ens_pdaf(iter, dim_p, dim_ens, dim_cvec_ens, ens_p, v_p, Vv_p) bind(c) + use iso_c_binding, only: c_double, c_int + IMPLICIT NONE + ! Iteration of optimization + INTEGER(c_int), INTENT(in) :: iter + ! PE-local dimension of state + INTEGER(c_int), INTENT(in) :: dim_p + ! Ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! Dimension of control vector + INTEGER(c_int), INTENT(in) :: dim_cvec_ens + ! PE-local ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(in) :: ens_p + ! PE-local control vector + REAL(c_double), DIMENSION(dim_cvec_ens), INTENT(in) :: v_p + ! PE-local state increment + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: Vv_p + END SUBROUTINE c__cvt_ens_pdaf + + SUBROUTINE c__obs_op_adj_pdaf(step, dim_p, dim_obs_p, m_state_p, state_p) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of state + INTEGER(c_int), INTENT(in) :: dim_p + ! Dimension of observed state + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! PE-local observed state + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: m_state_p + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + END SUBROUTINE c__obs_op_adj_pdaf + + SUBROUTINE c__likelihood_hyb_l_pdaf(domain_p, step, dim_obs_l, obs_l, resid_l, gamma, likely_l) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! Index of current local analysis domain + integer(c_int), intent(in) :: domain_p + ! Current time step + integer(c_int), intent(in) :: step + ! Number of local observations at current time step (i.e. the size of the local observation vector) + integer(c_int), intent(in) :: dim_obs_l + ! Local vector of observations + real(c_double), dimension(dim_obs_l), intent(in) :: obs_l + ! Hybrid weight provided by PDAF + real(c_double), intent(in) :: gamma + ! Input vector holding the local residual + real(c_double), dimension(dim_obs_l), intent(inout) :: resid_l + ! Output value of the local likelihood + real(c_double), intent(out) :: likely_l + END SUBROUTINE c__likelihood_hyb_l_pdaf + + SUBROUTINE c__prodRinvA_hyb_l_pdaf(domain_p, step, dim_obs_l, rank, obs_l, gamma, A_l, C_l) bind(c) + use iso_c_binding, only: c_double, c_int + implicit none + ! Index of current local analysis domain + integer(c_int), intent(in) :: domain_p + ! Current time step + integer(c_int), intent(in) :: step + ! Number of local observations at current time step (i.e. the size of the local observation vector) + integer(c_int), intent(in) :: dim_obs_l + ! Number of the columns in the matrix processes here. This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + integer(c_int), intent(in) :: rank + ! Local vector of observations + real(c_double), dimension(dim_obs_l), intent(in) :: obs_l + ! Hybrid weight provided by PDAF + real(c_double), intent(in) :: gamma + ! Input matrix provided by PDAF + real(c_double), dimension(dim_obs_l, rank), intent(inout) :: A_l + ! Output matrix + real(c_double), dimension(dim_obs_l, rank), intent(out) :: C_l + END SUBROUTINE c__prodRinvA_hyb_l_pdaf +end interface + +end module pdaf_c_cb_interface \ No newline at end of file diff --git a/pyPDAF/source/src/fortran/pdaf_c_diag.f90 b/pyPDAF/source/src/fortran/pdaf_c_diag.f90 new file mode 100644 index 0000000000000000000000000000000000000000..7d33fe5a0dcf1676ce5304351b4d1ea684710f3f --- /dev/null +++ b/pyPDAF/source/src/fortran/pdaf_c_diag.f90 @@ -0,0 +1,341 @@ +MODULE pdaf_c_diag +use iso_c_binding, only: c_int, c_double, c_bool +use PDAF + +implicit none + +contains + SUBROUTINE c__PDAF_diag_ensmean(dim, dim_ens, state, ens, status) bind(c) + ! state dimension + INTEGER(c_int), INTENT(in) :: dim + ! Ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! State vector + REAL(c_double), DIMENSION(dim), INTENT(inout) :: state + ! State ensemble + REAL(c_double), DIMENSION(dim, dim_ens), INTENT(in) :: ens + ! Status flag (0=success) + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_diag_ensmean(dim, dim_ens, state, ens, status) + + END SUBROUTINE c__PDAF_diag_ensmean + + SUBROUTINE c__PDAF_diag_stddev_nompi(dim, dim_ens, state, ens, stddev, & + do_mean, status) bind(c) + ! state dimension + INTEGER(c_int), INTENT(in) :: dim + ! Ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! State vector + REAL(c_double), DIMENSION(dim), INTENT(inout) :: state + ! State ensemble + REAL(c_double), DIMENSION(dim, dim_ens), INTENT(in) :: ens + ! Standard deviation of ensemble + REAL(c_double), INTENT(out) :: stddev + ! Whether to compute ensemble mean + INTEGER(c_int), INTENT(in) :: do_mean + ! Status flag (0=success) + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_diag_stddev_nompi(dim, dim_ens, state, ens, stddev, do_mean, & + status) + + END SUBROUTINE c__PDAF_diag_stddev_nompi + + SUBROUTINE c__PDAF_diag_stddev(dim_p, dim_ens, state_p, ens_p, stddev_g, & + do_mean, comm_filter, status) bind(c) + ! state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! Ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! State vector + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! State ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(in) :: ens_p + ! Global mean standard deviation of ensemble + REAL(c_double), INTENT(out) :: stddev_g + ! Whether to compute ensemble mean + INTEGER(c_int), INTENT(in) :: do_mean + ! Filter communicator + INTEGER(c_int), INTENT(in) :: comm_filter + ! Status flag (0=success) + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_diag_stddev(dim_p, dim_ens, state_p, ens_p, stddev_g, do_mean, & + comm_filter, status) + + END SUBROUTINE c__PDAF_diag_stddev + + SUBROUTINE c__PDAF_diag_variance_nompi(dim, dim_ens, state, ens, variance, & + stddev, do_mean, do_stddev, status) bind(c) + ! state dimension + INTEGER(c_int), INTENT(in) :: dim + ! Ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! State vector + REAL(c_double), DIMENSION(dim), INTENT(inout) :: state + ! State ensemble + REAL(c_double), DIMENSION(dim, dim_ens), INTENT(in) :: ens + ! Variance state vector + REAL(c_double), DIMENSION(dim), INTENT(out) :: variance + ! Standard deviation of ensemble + REAL(c_double), INTENT(out) :: stddev + ! Whether to compute ensemble mean + INTEGER(c_int), INTENT(in) :: do_mean + ! Whether to compute the ensemble mean standard deviation + INTEGER(c_int), INTENT(in) :: do_stddev + ! Status flag (0=success) + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_diag_variance_nompi(dim, dim_ens, state, ens, variance, stddev, & + do_mean, do_stddev, status) + + END SUBROUTINE c__PDAF_diag_variance_nompi + + SUBROUTINE c__PDAF_diag_variance(dim_p, dim_ens, state_p, ens_p, variance_p, & + stddev_g, do_mean, do_stddev, comm_filter, status) bind(c) + ! state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! Ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! State vector + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! State ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(in) :: ens_p + ! Variance state vector + REAL(c_double), DIMENSION(dim_p), INTENT(out) :: variance_p + ! Global standard deviation of ensemble + REAL(c_double), INTENT(out) :: stddev_g + ! Whether to compute ensemble mean + INTEGER(c_int), INTENT(in) :: do_mean + ! Whether to compute the ensemble mean standard deviation + INTEGER(c_int), INTENT(in) :: do_stddev + ! Filter communicator + INTEGER(c_int), INTENT(in) :: comm_filter + ! Status flag (0=success) + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_diag_variance(dim_p, dim_ens, state_p, ens_p, variance_p, & + stddev_g, do_mean, do_stddev, comm_filter, status) + + END SUBROUTINE c__PDAF_diag_variance + + SUBROUTINE c__PDAF_diag_rmsd_nompi(dim_p, statea_p, stateb_p, rmsd_p, & + status) bind(c) + ! state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! State vector A + REAL(c_double), DIMENSION(dim_p), INTENT(in) :: statea_p + ! State vector B + REAL(c_double), DIMENSION(dim_p), INTENT(in) :: stateb_p + ! RSMD + REAL(c_double), INTENT(out) :: rmsd_p + ! Status flag (0=success) + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_diag_rmsd_nompi(dim_p, statea_p, stateb_p, rmsd_p, status) + + END SUBROUTINE c__PDAF_diag_rmsd_nompi + + SUBROUTINE c__PDAF_diag_rmsd(dim_p, statea_p, stateb_p, rmsd_g, comm_filter, & + status) bind(c) + ! state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! State vector A + REAL(c_double), DIMENSION(dim_p), INTENT(in) :: statea_p + ! State vector B + REAL(c_double), DIMENSION(dim_p), INTENT(in) :: stateb_p + ! Global RSMD + REAL(c_double), INTENT(out) :: rmsd_g + ! Filter communicator + INTEGER(c_int), INTENT(in) :: comm_filter + ! Status flag (0=success) + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_diag_rmsd(dim_p, statea_p, stateb_p, rmsd_g, comm_filter, status) + + END SUBROUTINE c__PDAF_diag_rmsd + + SUBROUTINE c__PDAF_diag_crps_mpi(dim_p, dim_ens, element, oens, obs, & + comm_filter, mype_filter, npes_filter, crps, reli, pot_crps, uncert, & + status) bind(c) + ! PE-local state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! Ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! index of element in full state vector + INTEGER(c_int), INTENT(in) :: element + ! State ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(in) :: oens + ! Observation / truth + REAL(c_double), DIMENSION(dim_p), INTENT(in) :: obs + ! MPI communicator for filter + INTEGER(c_int), INTENT(in) :: comm_filter + ! rank of MPI communicator + INTEGER(c_int), INTENT(in) :: mype_filter + ! size of MPI communicator + INTEGER(c_int), INTENT(in) :: npes_filter + ! CRPS + REAL(c_double), INTENT(out) :: crps + ! Reliability + REAL(c_double), INTENT(out) :: reli + ! potential CRPS + REAL(c_double), INTENT(out) :: pot_crps + ! uncertainty + REAL(c_double), INTENT(out) :: uncert + ! Status flag (0=success) + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_diag_crps_mpi(dim_p, dim_ens, element, oens, obs, comm_filter, & + mype_filter, npes_filter, crps, reli, pot_crps, uncert, status) + + END SUBROUTINE c__PDAF_diag_crps_mpi + + SUBROUTINE c__PDAF_diag_CRPS_nompi(dim, dim_ens, element, oens, obs, crps, & + reli, resol, uncert, status) bind(c) + ! PE-local state dimension + INTEGER(c_int), INTENT(in) :: dim + ! Ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! ID of element to be used + INTEGER(c_int), INTENT(in) :: element + ! State ensemble + REAL(c_double), DIMENSION(dim, dim_ens), INTENT(in) :: oens + ! State ensemble + REAL(c_double), DIMENSION(dim), INTENT(in) :: obs + ! CRPS + REAL(c_double), INTENT(out) :: crps + ! Reliability + REAL(c_double), INTENT(out) :: reli + ! resolution + REAL(c_double), INTENT(out) :: resol + ! uncertainty + REAL(c_double), INTENT(out) :: uncert + ! Status flag (0=success) + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_diag_CRPS_nompi(dim, dim_ens, element, oens, obs, crps, reli, & + resol, uncert, status) + + END SUBROUTINE c__PDAF_diag_CRPS_nompi + + SUBROUTINE c__PDAF_diag_effsample(dim_sample, weights, n_eff) bind(c) + ! Sample size + INTEGER(c_int), INTENT(in) :: dim_sample + ! Weights of the samples + REAL(c_double), DIMENSION(dim_sample), INTENT(in) :: weights + ! Effecfive sample size + REAL(c_double), INTENT(out) :: n_eff + + + call PDAF_diag_effsample(dim_sample, weights, n_eff) + + END SUBROUTINE c__PDAF_diag_effsample + + SUBROUTINE c__PDAF_diag_ensstats(dim, dim_ens, element, state, ens, & + skewness, kurtosis, status) bind(c) + ! PE-local state dimension + INTEGER(c_int), INTENT(in) :: dim + ! Ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! ID of element to be used + INTEGER(c_int), INTENT(in) :: element + ! State vector + REAL(c_double), DIMENSION(dim), INTENT(in) :: state + ! State ensemble + REAL(c_double), DIMENSION(dim, dim_ens), INTENT(in) :: ens + ! Skewness of ensemble + REAL(c_double), INTENT(out) :: skewness + ! Kurtosis of ensemble + REAL(c_double), INTENT(out) :: kurtosis + ! Status flag (0=success) + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_diag_ensstats(dim, dim_ens, element, state, ens, skewness, & + kurtosis, status) + + END SUBROUTINE c__PDAF_diag_ensstats + + SUBROUTINE c__PDAF_diag_compute_moments(dim_p, dim_ens, ens, kmax, moments, & + bias) bind(c) + ! local size of the state + INTEGER(c_int), INTENT(in) :: dim_p + ! number of ensemble members/samples + INTEGER(c_int), INTENT(in) :: dim_ens + ! ensemble matrix + REAL(c_double), DIMENSION(dim_p,dim_ens), INTENT(in) :: ens + ! maximum order of central moment that is computed, maximum is 4 + INTEGER(c_int), INTENT(in) :: kmax + ! The columns contain the moments of the ensemble + REAL(c_double), DIMENSION(dim_p, kmax), INTENT(out) :: moments + ! if 0 bias correction is applied (default) + INTEGER(c_int), INTENT(in) :: bias + + + call PDAF_diag_compute_moments(dim_p, dim_ens, ens, kmax, moments, bias) + + END SUBROUTINE c__PDAF_diag_compute_moments + + SUBROUTINE c__PDAF_diag_histogram(ncall, dim, dim_ens, element, state, ens, & + hist, delta, status) bind(c) + ! Number of calls to routine + INTEGER(c_int), INTENT(in) :: ncall + ! State dimension + INTEGER(c_int), INTENT(in) :: dim + ! Ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! Element of vector used for histogram + INTEGER(c_int), INTENT(in) :: element + ! State vector + REAL(c_double), DIMENSION(dim), INTENT(in) :: state + ! State ensemble + REAL(c_double), DIMENSION(dim, dim_ens), INTENT(in) :: ens + ! Histogram about the state + INTEGER(c_int), DIMENSION(dim_ens+1), INTENT(inout) :: hist + ! deviation measure from flat histogram + REAL(c_double), INTENT(out) :: delta + ! Status flag (0=success) + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_diag_histogram(ncall, dim, dim_ens, element, state, ens, hist, & + delta, status) + + END SUBROUTINE c__PDAF_diag_histogram + + SUBROUTINE c__PDAF_diag_reliability_budget(n_times, dim_ens, dim_p, ens_p, & + obsvar, obs_p, budget, bias_2) bind(c) + ! Number of time steps + INTEGER(c_int), INTENT(in) :: n_times + ! Number of ensemble members + INTEGER(c_int), INTENT(in) :: dim_ens + ! Dimension of the state vector + INTEGER(c_int), INTENT(in) :: dim_p + ! Ensemble matrix over times + REAL(c_double), DIMENSION(dim_p, dim_ens, n_times), INTENT(in) :: ens_p + ! Squared observation error/variance at n_times + REAL(c_double), DIMENSION(dim_p, dim_ens, n_times), INTENT(in) :: obsvar + ! Observation vector + REAL(c_double), DIMENSION(dim_p, n_times), INTENT(in) :: obs_p + ! Budget term for a single time step + REAL(c_double), DIMENSION(dim_p, n_times, 5), INTENT(out) :: budget + ! bias^2 uses + REAL(c_double), DIMENSION(dim_p), INTENT(out) :: bias_2 + + + call PDAF_diag_reliability_budget(n_times, dim_ens, dim_p, ens_p, obsvar, & + obs_p, budget, bias_2) + + END SUBROUTINE c__PDAF_diag_reliability_budget +END MODULE pdaf_c_diag diff --git a/pyPDAF/source/src/fortran/pdaf_c_f_interface.f90 b/pyPDAF/source/src/fortran/pdaf_c_f_interface.f90 new file mode 100644 index 0000000000000000000000000000000000000000..af49e41f6dcf2783845786183082ca7bab209991 --- /dev/null +++ b/pyPDAF/source/src/fortran/pdaf_c_f_interface.f90 @@ -0,0 +1,638 @@ +module pdaf_c_f_interface +use pdaf_c_cb_interface +implicit none + +procedure(c__init_ens_pdaf), pointer :: init_ens_pdaf_c_ptr => null() +procedure(c__add_obs_err_pdaf), pointer :: add_obs_err_pdaf_c_ptr => null() +procedure(c__next_observation_pdaf), pointer :: next_observation_pdaf_c_ptr => null() +procedure(c__collect_state_pdaf), pointer :: collect_state_pdaf_c_ptr => null() +procedure(c__distribute_state_pdaf), pointer :: distribute_state_pdaf_c_ptr => null() +procedure(c__prepoststep_pdaf), pointer :: prepoststep_pdaf_c_ptr => null() + +procedure(c__init_dim_obs_pdaf), pointer :: init_dim_obs_pdaf_c_ptr => null() +procedure(c__init_dim_obs_pdaf), pointer :: init_dim_obs_f_pdaf_c_ptr => null() +procedure(c__init_obs_pdaf), pointer :: init_obs_pdaf_c_ptr => null() +procedure(c__init_obs_pdaf), pointer :: init_obs_f_pdaf_c_ptr => null() +procedure(c__init_obs_covar_pdaf), pointer :: init_obs_covar_pdaf_c_ptr => null() +procedure(c__init_obsvar_pdaf), pointer :: init_obsvar_pdaf_c_ptr => null() +procedure(c__init_obsvars_pdaf), pointer :: init_obsvars_pdaf_c_ptr => null() +procedure(c__prodRinvA_pdaf), pointer :: prodRinvA_pdaf_c_ptr => null() +procedure(c__obs_op_pdaf), pointer :: obs_op_pdaf_c_ptr => null() +procedure(c__obs_op_pdaf), pointer :: obs_op_f_pdaf_c_ptr => null() +procedure(c__obs_op_pdaf), pointer :: obs_op_lin_pdaf_c_ptr => null() +procedure(c__obs_op_adj_pdaf), pointer :: obs_op_adj_pdaf_c_ptr => null() + +procedure(c__g2l_obs_pdaf), pointer :: g2l_obs_pdaf_c_ptr => null() +procedure(c__g2l_state_pdaf), pointer :: g2l_state_pdaf_c_ptr => null() +procedure(c__init_dim_l_pdaf), pointer :: init_dim_l_pdaf_c_ptr => null() +procedure(c__init_dim_obs_l_pdaf), pointer :: init_dim_obs_l_pdaf_c_ptr => null() +procedure(c__init_n_domains_p_pdaf), pointer :: init_n_domains_p_pdaf_c_ptr => null() +procedure(c__init_obs_l_pdaf), pointer :: init_obs_l_pdaf_c_ptr => null() +procedure(c__init_obsvar_l_pdaf), pointer :: init_obsvar_l_pdaf_c_ptr => null() +procedure(c__init_obserr_f_pdaf), pointer :: init_obserr_f_pdaf_c_ptr => null() +procedure(c__l2g_state_pdaf), pointer :: l2g_state_pdaf_c_ptr => null() +procedure(c__localize_covar_pdaf), pointer :: localize_covar_pdaf_c_ptr => null() +procedure(c__localize_covar_serial_pdaf), pointer :: localize_covar_serial_pdaf_c_ptr => null() +procedure(c__likelihood_pdaf), pointer :: likelihood_pdaf_c_ptr => null() +procedure(c__likelihood_l_pdaf), pointer :: likelihood_l_pdaf_c_ptr => null() + +procedure(c__get_obs_f_pdaf), pointer :: get_obs_f_pdaf_c_ptr => null() + +procedure(c__cvt_pdaf), pointer :: cvt_pdaf_c_ptr => null() +procedure(c__cvt_ens_pdaf), pointer :: cvt_ens_pdaf_c_ptr => null() +procedure(c__cvt_adj_pdaf), pointer :: cvt_adj_pdaf_c_ptr => null() +procedure(c__cvt_adj_ens_pdaf), pointer :: cvt_adj_ens_pdaf_c_ptr => null() +procedure(c__likelihood_hyb_l_pdaf), pointer :: likelihood_hyb_l_pdaf_c_ptr => null() + +procedure(c__prodRinvA_l_pdaf), pointer :: prodRinvA_l_pdaf_c_ptr => null() +procedure(c__prodRinvA_hyb_l_pdaf), pointer :: prodRinvA_hyb_l_pdaf_c_ptr => null() + + +contains + SUBROUTINE f__add_obs_err_pdaf(step, dim_obs_p, C_p) + IMPLICIT NONE + INTEGER, INTENT(in) :: step + INTEGER, INTENT(in) :: dim_obs_p + REAL, DIMENSION(dim_obs_p,dim_obs_p), INTENT(inout) :: C_p + call add_obs_err_pdaf_c_ptr(step, dim_obs_p, C_p) + END SUBROUTINE f__add_obs_err_pdaf + + SUBROUTINE f__init_ens_pdaf(filtertype, dim_p, dim_ens, state_p, uinv, ens_p, flag) + implicit none + integer, intent(in) :: filtertype + integer, intent(in) :: dim_p + integer, intent(in) :: dim_ens + real, DIMENSION(dim_p), intent(inout) :: state_p + real, DIMENSION(dim_ens - 1, dim_ens-1), intent(inout) :: uinv + real, DIMENSION(dim_p, dim_ens), intent(inout) :: ens_p + integer, intent(inout) :: flag + + call init_ens_pdaf_c_ptr(filtertype, dim_p, dim_ens, state_p, uinv, ens_p, flag) + end subroutine f__init_ens_pdaf + + subroutine f__next_observation_pdaf(stepnow, nsteps, doexit, time) + implicit none + ! the current time step given by PDAF + integer, intent(in) :: stepnow + ! number of forecast time steps until next assimilation; + ! this can also be interpreted as + ! number of assimilation function calls + ! to perform a new assimilation + integer, intent(out) :: nsteps + ! whether to exit forecasting (1 for exit) + integer, intent(out) :: doexit + ! current model (physical) time + real, intent(out) :: time + + call next_observation_pdaf_c_ptr(stepnow, nsteps, doexit, time) + end subroutine f__next_observation_pdaf + + subroutine f__collect_state_pdaf(dim_p, state_p) + implicit none + ! pe-local state dimension + integer, intent(in) :: dim_p + ! local state vector + real, DIMENSION(dim_p), intent(inout) :: state_p + call collect_state_pdaf_c_ptr(dim_p, state_p) + end subroutine f__collect_state_pdaf + + subroutine f__distribute_state_pdaf(dim_p, state_p) + implicit none + ! PE-local state dimension + integer, intent(in) :: dim_p + ! PE-local state vector + real, DIMENSION(dim_p), intent(inout) :: state_p + call distribute_state_pdaf_c_ptr(dim_p, state_p) + end subroutine f__distribute_state_pdaf + + subroutine f__prepoststep_pdaf(step, dim_p, dim_ens, dim_ens_l, & + dim_obs_p, state_p, uinv, ens_p, flag) + implicit none + ! current time step + ! (negative for call before analysis/preprocessing) + integer, intent(in) :: step + ! PE-local state vector dimension + integer, intent(in) :: dim_p + ! number of ensemble members + integer, intent(in) :: dim_ens + ! number of ensemble members run serially + ! on each model task + integer, intent(in) :: dim_ens_l + ! PE-local dimension of observation vector + integer, intent(in) :: dim_obs_p + ! pe-local forecast/analysis state + ! (the array 'state_p' is generally not + ! initialised in the case of ESTKF/ETKF/EnKF/SEIK, + ! so it can be used freely here.) + real, DIMENSION(dim_p), intent(inout) :: state_p + ! Inverse of the transformation matrix in ETKF and ESKTF; + ! inverse of matrix formed by right singular vectors of error + ! covariance matrix of ensemble perturbations in SEIK/SEEK. + ! not used in EnKF. + real, DIMENSION(dim_ens-1, dim_ens-1), intent(inout) :: uinv + ! PE-local ensemble + real, DIMENSION(dim_p, dim_ens), intent(inout) :: ens_p + ! pdaf status flag + integer, intent(in) :: flag + call prepoststep_pdaf_c_ptr(step, dim_p, dim_ens, dim_ens_l, & + dim_obs_p, state_p, uinv, ens_p, flag) + end subroutine f__prepoststep_pdaf + + subroutine f__init_dim_obs_pdaf(step, dim_obs_p) + implicit none + ! current time step + integer, intent(in) :: step + ! dimension of observation vector + integer, intent(out) :: dim_obs_p + + call init_dim_obs_pdaf_c_ptr(step, dim_obs_p) + end subroutine f__init_dim_obs_pdaf + + subroutine f__init_dim_obs_f_pdaf(step, dim_obs_p) + implicit none + ! current time step + integer, intent(in) :: step + ! dimension of observation vector + integer, intent(out) :: dim_obs_p + call init_dim_obs_f_pdaf_c_ptr(step, dim_obs_p) + end subroutine f__init_dim_obs_f_pdaf + + SUBROUTINE f__init_obs_pdaf(step, dim_obs_p, observation_p) + implicit none + ! Current time step + integer, intent(in) :: step + ! Size of the observation vector + integer, intent(in) :: dim_obs_p + ! Vector of observations + real, DIMENSION(dim_obs_p), intent(out) :: observation_p + call init_obs_pdaf_c_ptr(step, dim_obs_p, observation_p) + END SUBROUTINE f__init_obs_pdaf + + SUBROUTINE f__init_obs_covar_pdaf(step, dim_obs, dim_obs_p, covar, obs_p, isdiag) + use iso_c_binding, only: c_bool + implicit none + ! Current time step + integer, intent(in) :: step + ! Global size of observation vector + integer, intent(in) :: dim_obs + ! Size of process-local observation vector + integer, intent(in) :: dim_obs_p + ! Observation error covariance matrix + real, intent(out), dimension(dim_obs,dim_obs) :: covar + ! Process-local vector of observations + real, intent(in), dimension(dim_obs_p) :: obs_p + logical, intent(out) :: isdiag + + logical(c_bool) :: isdiag_c + call init_obs_covar_pdaf_c_ptr(step, dim_obs, dim_obs_p, covar, obs_p, isdiag_c) + isdiag = isdiag_c + END SUBROUTINE f__init_obs_covar_pdaf + + SUBROUTINE f__init_obsvar_pdaf(step, dim_obs_p, obs_p, meanvar) + implicit none + ! Current time step + integer, intent(in) :: step + ! Size of observation vector + integer, intent(in) :: dim_obs_p + ! Vector of observations + real, intent(in), dimension(dim_obs_p) :: obs_p + ! Mean observation error variance + real, intent(out) :: meanvar + call init_obsvar_pdaf_c_ptr(step, dim_obs_p, obs_p, meanvar) + END SUBROUTINE f__init_obsvar_pdaf + + SUBROUTINE f__init_obsvars_pdaf(step, dim_obs_f, var_f) + IMPLICIT NONE + ! Current time step + INTEGER, INTENT(in) :: step + ! Dimension of full observation vector + INTEGER, INTENT(in) :: dim_obs_f + ! vector of observation error variances + REAL, DIMENSION(dim_obs_f), INTENT(out) :: var_f + + call init_obsvars_pdaf_c_ptr(step, dim_obs_f, var_f) + END SUBROUTINE f__init_obsvars_pdaf + + SUBROUTINE f__prodRinvA_pdaf(step, dim_obs_p, rank, obs_p, A_p, C_p) + implicit none + ! Current time step + integer, intent(in) :: step + ! Number of observations at current time step (i.e. the size of the observation vector) + integer, intent(in) :: dim_obs_p + ! Number of the columns in the matrix processes here. + ! This is usually the ensemble size minus one + ! (or the rank of the initial covariance matrix) + integer, intent(in) :: rank + ! Vector of observations + real, intent(in), dimension(dim_obs_p) :: obs_p + ! Input matrix provided by PDAF + real, intent(in), dimension(dim_obs_p, rank) :: A_p + ! Output matrix + real, intent(out), dimension(dim_obs_p, rank) :: C_p + call prodRinvA_pdaf_c_ptr(step, dim_obs_p, rank, obs_p, A_p, C_p) + END SUBROUTINE f__prodRinvA_pdaf + + SUBROUTINE f__obs_op_pdaf(step, dim_p, dim_obs_p, state_p, m_state_p) + implicit none + ! Current time step + integer, intent(in) :: step + ! Size of state vector + ! (local part in case of parallel decomposed state) + integer, intent(in) :: dim_p + ! Size of PE-local observation vector + integer, intent(in) :: dim_obs_p + ! Model state vector + real, intent(in), dimension(dim_p) :: state_p + ! Observed state vector + ! (i.e. the result after applying the observation operator to state_p) + real, intent(inout), dimension(dim_obs_p) :: m_state_p + call obs_op_pdaf_c_ptr(step, dim_p, dim_obs_p, state_p, m_state_p) + END SUBROUTINE f__obs_op_pdaf + + SUBROUTINE f__obs_op_f_pdaf(step, dim_p, dim_obs_p, state_p, m_state_p) + implicit none + ! Current time step + integer, intent(in) :: step + ! Size of state vector (local part in case of parallel decomposed state) + integer, intent(in) :: dim_p + ! Size of observation vector + integer, intent(in) :: dim_obs_p + ! Model state vector + real, intent(in), dimension(dim_p) :: state_p + ! Observed state vector (i.e. the result after applying the observation operator to state_p) + real, intent(out), dimension(dim_obs_p) :: m_state_p + call obs_op_f_pdaf_c_ptr(step, dim_p, dim_obs_p, state_p, m_state_p) + END SUBROUTINE f__obs_op_f_pdaf + + SUBROUTINE f__g2l_obs_pdaf(domain_p, step, dim_obs_f, dim_obs_l, mstate_f, mstate_l) + implicit none + ! Index of current local analysis domain + integer, intent(in) :: domain_p + ! Current time step + integer, intent(in) :: step + ! Size of full observation vector for model sub-domain + integer, intent(in) :: dim_obs_f + ! Size of observation vector for local analysis domain + integer, intent(in) :: dim_obs_l + ! Full observation vector for model sub-domain + integer, intent(in), dimension(dim_obs_f) :: mstate_f + ! Observation vector for local analysis domain + integer, intent(out), dimension(dim_obs_l) :: mstate_l + call g2l_obs_pdaf_c_ptr(domain_p, step, dim_obs_f, dim_obs_l, mstate_f, mstate_l) + END SUBROUTINE f__g2l_obs_pdaf + + subroutine f__g2l_state_pdaf(step, domain_p, dim_p, state_p, dim_l, state_l) + + implicit none + ! current time step + integer, intent(in) :: step + ! current local analysis domain + integer, intent(in) :: domain_p + ! pe-local full state dimension + integer, intent(in) :: dim_p + ! local state dimension + integer, intent(in) :: dim_l + ! pe-local full state vector + real, dimension(dim_p), intent(in) :: state_p + ! state vector on local analysis domain + real, dimension(dim_l), intent(out) :: state_l + call g2l_state_pdaf_c_ptr(step, domain_p, dim_p, state_p, dim_l, state_l) + end subroutine f__g2l_state_pdaf + + subroutine f__init_dim_l_pdaf(step, domain_p, dim_l) + implicit none + ! current time step + integer, intent(in) :: step + ! current local analysis domain + integer, intent(in) :: domain_p + ! local state dimension + integer, intent(out) :: dim_l + call init_dim_l_pdaf_c_ptr(step, domain_p, dim_l) + end subroutine f__init_dim_l_pdaf + + subroutine f__init_dim_obs_l_pdaf(domain_p, step, dim_obs_f, dim_obs_l) + implicit none + ! index of current local analysis domain + integer, intent(in) :: domain_p + ! current time step + integer, intent(in) :: step + ! full dimension of observation vector + integer, intent(in) :: dim_obs_f + ! local dimension of observation vector + integer, intent(out) :: dim_obs_l + call init_dim_obs_l_pdaf_c_ptr(domain_p, step, dim_obs_f, dim_obs_l) + end subroutine f__init_dim_obs_l_pdaf + + subroutine f__init_n_domains_p_pdaf(step, n_domains_p) + implicit none + ! current time step + integer, intent(in) :: step + ! pe-local number of analysis domains + integer, intent(out) :: n_domains_p + call init_n_domains_p_pdaf_c_ptr(step, n_domains_p) + end subroutine f__init_n_domains_p_pdaf + + SUBROUTINE f__init_obs_f_pdaf(step, dim_obs_f, observation_f) + implicit none + ! Current time step + integer, intent(in) :: step + ! Size of the full observation vector + integer, intent(in) :: dim_obs_f + ! Full vector of observations + real, intent(out), dimension(dim_obs_f) :: observation_f + call init_obs_f_pdaf_c_ptr(step, dim_obs_f, observation_f) + END SUBROUTINE f__init_obs_f_pdaf + + SUBROUTINE f__init_obs_l_pdaf(domain_p, step, dim_obs_l, observation_l) + implicit none + ! Index of current local analysis domain + integer, intent(in) :: domain_p + ! Current time step + integer, intent(in) :: step + ! Local size of the observation vector + integer, intent(in) :: dim_obs_l + ! Local vector of observations + real, intent(out), dimension(dim_obs_l) :: observation_l + call init_obs_l_pdaf_c_ptr(domain_p, step, dim_obs_l, observation_l) + END SUBROUTINE f__init_obs_l_pdaf + + SUBROUTINE f__init_obsvar_l_pdaf(domain_p, step, dim_obs_l, obs_l, dim_obs_p, meanvar_l) + implicit none + ! Index of current local analysis domain + integer, intent(in) :: domain_p + ! Current time step + integer, intent(in) :: step + ! Local dimension of observation vector + integer, intent(in) :: dim_obs_l + ! Dimension of local observation vector + integer, intent(in) :: dim_obs_p + ! Local observation vector + real, intent(in), dimension(dim_obs_p) :: obs_l + ! Mean local observation error variance + real, intent(out) :: meanvar_l + call init_obsvar_l_pdaf_c_ptr(domain_p, step, dim_obs_l, obs_l, dim_obs_p, meanvar_l) + END SUBROUTINE f__init_obsvar_l_pdaf + + SUBROUTINE f__init_obserr_f_pdaf(step, dim_obs_f, obs_f, obserr_f) + IMPLICIT NONE + ! Current time step + INTEGER, INTENT(in) :: step + ! Full dimension of observation vector + INTEGER, INTENT(in) :: dim_obs_f + ! Full observation vector + REAL, DIMENSION(dim_obs_f), INTENT(in) :: obs_f + ! Full observation error stddev + REAL, DIMENSION(dim_obs_f), INTENT(out) :: obserr_f + call init_obserr_f_pdaf_c_ptr(step, dim_obs_f, obs_f, obserr_f) + END SUBROUTINE f__init_obserr_f_pdaf + + subroutine f__l2g_state_pdaf(step, domain_p, dim_l, state_l, dim_p, state_p) + implicit none + ! current time step + integer, intent(in) :: step + ! current local analysis domain + integer, intent(in) :: domain_p + ! local state dimension + integer, intent(in) :: dim_l + ! pe-local full state dimension + integer, intent(in) :: dim_p + ! state vector on local analysis domain + real, DIMENSION(dim_l), intent(in) :: state_l + ! pe-local full state vector + real, DIMENSION(dim_p), intent(inout) :: state_p + call l2g_state_pdaf_c_ptr(step, domain_p, dim_l, state_l, dim_p, state_p) + end subroutine f__l2g_state_pdaf + + SUBROUTINE f__prodRinvA_l_pdaf(domain_p, step, dim_obs_l, rank, obs_l, A_l, C_l) + implicit none + ! Index of current local analysis domain + integer, intent(in) :: domain_p + ! Current time step + integer, intent(in) :: step + ! Number of local observations at current time step (i.e. the size of the local observation vector) + integer, intent(in) :: dim_obs_l + ! Number of the columns in the matrix processes here. + ! This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + integer, intent(in) :: rank + ! Local vector of observations + real, intent(in), dimension(dim_obs_l) :: obs_l + ! Input matrix provided by PDAF + real, intent(inout), dimension(dim_obs_l, rank) :: A_l + ! Output matrix + real, intent(out), dimension(dim_obs_l, rank) :: C_l + call prodRinvA_l_pdaf_c_ptr(domain_p, step, dim_obs_l, rank, obs_l, A_l, C_l) + END SUBROUTINE f__prodRinvA_l_pdaf + + subroutine f__localize_covar_pdaf(dim_p, dim_obs, hp_p, hph) + implicit none + ! pe-local state dimension + integer, intent(in) :: dim_p + ! number of observations + integer, intent(in) :: dim_obs + ! pe local part of matrix hp + real, DIMENSION(dim_obs, dim_p), intent(inout) :: hp_p + ! matrix hph + real, DIMENSION(dim_obs, dim_obs), intent(inout) :: hph + call localize_covar_pdaf_c_ptr(dim_p, dim_obs, hp_p, hph) + end subroutine f__localize_covar_pdaf + + SUBROUTINE f__localize_covar_serial_pdaf(iobs, dim_p, dim_obs, HP_p, HXY_p) + IMPLICIT NONE + ! Index of current observation + INTEGER, INTENT(in) :: iobs + ! Process-local state dimension + INTEGER, INTENT(in) :: dim_p + ! Number of observations + INTEGER, INTENT(in) :: dim_obs + ! Process-local part of matrix HP for observation iobs + REAL, DIMENSION(dim_p), INTENT(inout) :: HP_p + ! Process-local part of matrix HX(HX_all) for full observations + REAL, DIMENSION(dim_obs), INTENT(inout) :: HXY_p + call localize_covar_serial_pdaf_c_ptr(iobs, dim_p, dim_obs, HP_p, HXY_p) + END SUBROUTINE f__localize_covar_serial_pdaf + + + SUBROUTINE f__likelihood_pdaf(step, dim_obs_p, obs_p, resid, likely) + implicit none + ! Current time step + integer, intent(in) :: step + ! Number of observations at current time step (i.e. the size of the observation vector) + integer, intent(in) :: dim_obs_p + ! Vector of observations + real, intent(in), dimension(dim_obs_p) :: obs_p + ! Input vector holding the residual + real, intent(in), dimension(dim_obs_p) :: resid + ! Output value of the likelihood + real, intent(out) :: likely + call likelihood_pdaf_c_ptr(step, dim_obs_p, obs_p, resid, likely) + END SUBROUTINE f__likelihood_pdaf + + SUBROUTINE f__likelihood_l_pdaf(domain_p, step, dim_obs_l, obs_l, resid_l, likely_l) + implicit none + ! Index of current local analysis domain + integer, intent(in) :: domain_p + ! Current time step + integer, intent(in) :: step + ! Number of local observations at current time step (i.e. the size of the local observation vector) + integer, intent(in) :: dim_obs_l + ! Local vector of observations + real, intent(in), dimension(dim_obs_l) :: obs_l + ! nput vector holding the local residual + real, intent(inout), dimension(dim_obs_l) :: resid_l + ! Output value of the local likelihood + real, intent(out) :: likely_l + call likelihood_l_pdaf_c_ptr(domain_p, step, dim_obs_l, obs_l, resid_l, likely_l) + END SUBROUTINE f__likelihood_l_pdaf + + SUBROUTINE f__get_obs_f_pdaf(step, dim_obs_f, observation_f) + implicit none + ! Current time step + integer, intent(in) :: step + ! Size of the full observation vector + integer, intent(in) :: dim_obs_f + ! Full vector of synthetic observations (process-local) + real, intent(in), dimension(dim_obs_f) :: observation_f + call get_obs_f_pdaf_c_ptr(step, dim_obs_f, observation_f) + END SUBROUTINE f__get_obs_f_pdaf + + SUBROUTINE f__cvt_adj_ens_pdaf(iter, dim_p, dim_ens, dim_cv_ens_p, ens_p, Vcv_p, cv_p) + implicit none + ! Iteration of optimization + INTEGER, INTENT(in) :: iter + ! PE-local observation dimension + INTEGER, INTENT(in) :: dim_p + ! Ensemble size + INTEGER, INTENT(in) :: dim_ens + ! PE-local dimension of control vector + INTEGER, INTENT(in) :: dim_cv_ens_p + ! PE-local ensemble + REAL, DIMENSION(dim_p, dim_ens), INTENT(in) :: ens_p + ! PE-local input vector + REAL, DIMENSION(dim_p), INTENT(in) :: Vcv_p + ! PE-local result vector + REAL, DIMENSION(dim_cv_ens_p), INTENT(inout) :: cv_p + + call cvt_adj_ens_pdaf_c_ptr(iter, dim_p, dim_ens, dim_cv_ens_p, ens_p, Vcv_p, cv_p) + END SUBROUTINE f__cvt_adj_ens_pdaf + + SUBROUTINE f__cvt_adj_pdaf(iter, dim_p, dim_cvec, Vcv_p, cv_p) + implicit none + ! Iteration of optimization + INTEGER, INTENT(in) :: iter + ! PE-local observation dimension + INTEGER, INTENT(in) :: dim_p + ! Dimension of control vector + INTEGER, INTENT(in) :: dim_cvec + ! PE-local result vector (state vector increment) + REAL, DIMENSION(dim_p), INTENT(in) :: Vcv_p + ! PE-local control vector + REAL, DIMENSION(dim_cvec), INTENT(inout) :: cv_p + call cvt_adj_pdaf_c_ptr(iter, dim_p, dim_cvec, Vcv_p, cv_p) + END SUBROUTINE f__cvt_adj_pdaf + + SUBROUTINE f__cvt_pdaf(iter, dim_p, dim_cvec, cv_p, Vv_p) + implicit none + ! Iteration of optimization + INTEGER, INTENT(in) :: iter + ! PE-local observation dimension + INTEGER, INTENT(in) :: dim_p + ! Dimension of control vector + INTEGER, INTENT(in) :: dim_cvec + ! PE-local control vector + REAL, DIMENSION(dim_cvec), INTENT(in) :: cv_p + ! PE-local result vector (state vector increment) + REAL, DIMENSION(dim_p), INTENT(inout) :: Vv_p + call cvt_pdaf_c_ptr(iter, dim_p, dim_cvec, cv_p, Vv_p) + END SUBROUTINE f__cvt_pdaf + + SUBROUTINE f__cvt_ens_pdaf(iter, dim_p, dim_ens, dim_cvec_ens, ens_p, v_p, Vv_p) + IMPLICIT NONE + ! Iteration of optimization + INTEGER, INTENT(in) :: iter + ! PE-local dimension of state + INTEGER, INTENT(in) :: dim_p + ! Ensemble size + INTEGER, INTENT(in) :: dim_ens + ! Dimension of control vector + INTEGER, INTENT(in) :: dim_cvec_ens + ! PE-local ensemble + REAL, DIMENSION(dim_p, dim_ens), INTENT(in) :: ens_p + ! PE-local control vector + REAL, DIMENSION(dim_cvec_ens), INTENT(in) :: v_p + ! PE-local state increment + REAL, DIMENSION(dim_p), INTENT(inout) :: Vv_p + call cvt_ens_pdaf_c_ptr(iter, dim_p, dim_ens, dim_cvec_ens, ens_p, v_p, Vv_p) + END SUBROUTINE f__cvt_ens_pdaf + + SUBROUTINE f__obs_op_adj_pdaf(step, dim_p, dim_obs_p, m_state_p, state_p) + implicit none + ! Current time step + INTEGER, INTENT(in) :: step + ! PE-local dimension of state + INTEGER, INTENT(in) :: dim_p + ! Dimension of observed state + INTEGER, INTENT(in) :: dim_obs_p + ! PE-local observed state + REAL, DIMENSION(dim_obs_p), INTENT(in) :: m_state_p + ! PE-local model state + REAL, DIMENSION(dim_p), INTENT(inout) :: state_p + call obs_op_adj_pdaf_c_ptr(step, dim_p, dim_obs_p, m_state_p, state_p) + END SUBROUTINE f__obs_op_adj_pdaf + + SUBROUTINE f__obs_op_lin_pdaf(step, dim_p, dim_obs_p, state_p, m_state_p) + implicit none + ! Current time step + INTEGER, INTENT(in) :: step + ! PE-local dimension of state + INTEGER, INTENT(in) :: dim_p + ! Dimension of observed state + INTEGER, INTENT(in) :: dim_obs_p + ! PE-local model state + REAL, DIMENSION(dim_p), INTENT(in) :: state_p + ! PE-local observed state + REAL, DIMENSION(dim_obs_p), INTENT(inout) :: m_state_p + call obs_op_lin_pdaf_c_ptr(step, dim_p, dim_obs_p, state_p, m_state_p) + END SUBROUTINE f__obs_op_lin_pdaf + + SUBROUTINE f__likelihood_hyb_l_pdaf(domain_p, step, dim_obs_l, obs_l, resid_l, gamma, likely_l) + implicit none + ! Index of current local analysis domain + integer, intent(in) :: domain_p + ! Current time step + integer, intent(in) :: step + ! Number of local observations at current time step (i.e. the size of the local observation vector) + integer, intent(in) :: dim_obs_l + ! Local vector of observations + real, dimension(dim_obs_l), intent(in) :: obs_l + ! Hybrid weight provided by PDAF + real, intent(in) :: gamma + ! Input vector holding the local residual + real, dimension(dim_obs_l), intent(inout) :: resid_l + ! Output value of the local likelihood + real, intent(out) :: likely_l + call likelihood_hyb_l_pdaf_c_ptr(domain_p, step, dim_obs_l, obs_l, resid_l, gamma, likely_l) + END SUBROUTINE f__likelihood_hyb_l_pdaf + + SUBROUTINE f__prodRinvA_hyb_l_pdaf(domain_p, step, dim_obs_l, rank, obs_l, gamma, A_l, C_l) + + implicit none + ! Index of current local analysis domain + integer, intent(in) :: domain_p + ! Current time step + integer, intent(in) :: step + ! Number of local observations at current time step (i.e. the size of the local observation vector) + integer, intent(in) :: dim_obs_l + ! Number of the columns in the matrix processes here. This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + integer, intent(in) :: rank + ! Local vector of observations + real, dimension(dim_obs_l), intent(in) :: obs_l + ! Hybrid weight provided by PDAF + real, intent(in) :: gamma + ! Input matrix provided by PDAF + real, dimension(dim_obs_l, rank), intent(inout) :: A_l + ! Output matrix + real, dimension(dim_obs_l, rank), intent(out) :: C_l + call prodRinvA_hyb_l_pdaf_c_ptr(domain_p, step, dim_obs_l, rank, obs_l, gamma, A_l, C_l) + END SUBROUTINE f__prodRinvA_hyb_l_pdaf + +end module pdaf_c_f_interface \ No newline at end of file diff --git a/pyPDAF/source/src/fortran/pdaf_c_get.f90 b/pyPDAF/source/src/fortran/pdaf_c_get.f90 new file mode 100644 index 0000000000000000000000000000000000000000..fc56fabcf9d33b43739366099db30cff593e7ec6 --- /dev/null +++ b/pyPDAF/source/src/fortran/pdaf_c_get.f90 @@ -0,0 +1,63 @@ +MODULE pdaf_c_get +use iso_c_binding, only: c_int, c_double, c_bool +use PDAF +implicit none + +contains + SUBROUTINE c__PDAF_get_assim_flag(did_assim) bind(c) + ! Flag: (1) for assimilation; (0) else + INTEGER(c_int), INTENT(out) :: did_assim + + + call PDAF_get_assim_flag(did_assim) + + END SUBROUTINE c__PDAF_get_assim_flag + + SUBROUTINE c__PDAF_get_localfilter(localfilter_out) bind(c) + ! Whether the filter is domain-localized + INTEGER(c_int), INTENT(out) :: localfilter_out + + + call PDAF_get_localfilter(localfilter_out) + + END SUBROUTINE c__PDAF_get_localfilter + + SUBROUTINE c__PDAF_get_local_type(localtype) bind(c) + ! Localization type of the filter + INTEGER(c_int), INTENT(out) :: localtype + + + call PDAF_get_local_type(localtype) + + END SUBROUTINE c__PDAF_get_local_type + + SUBROUTINE c__PDAF_get_memberid(memberid) bind(c) + ! Index in the local ensemble + INTEGER(c_int), INTENT(inout) :: memberid + + + call PDAF_get_memberid(memberid) + + END SUBROUTINE c__PDAF_get_memberid + + SUBROUTINE c__PDAF_get_obsmemberid(memberid) bind(c) + ! Index in the local ensemble + INTEGER(c_int), INTENT(inout) :: memberid + + + call PDAF_get_obsmemberid(memberid) + + END SUBROUTINE c__PDAF_get_obsmemberid + + SUBROUTINE c__PDAF_get_smootherens(sens_point, maxlag, status) bind(c) + ! Pointer to smoother array + REAL(c_double), POINTER, DIMENSION(:,:,:), INTENT(out) :: sens_point + ! Number of past timesteps processed in sens + INTEGER(c_int), INTENT(out) :: maxlag + ! Status flag + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_get_smootherens(sens_point, maxlag, status) + END SUBROUTINE c__PDAF_get_smootherens +END MODULE pdaf_c_get diff --git a/pyPDAF/source/src/fortran/pdaf_c_iau.f90 b/pyPDAF/source/src/fortran/pdaf_c_iau.f90 new file mode 100644 index 0000000000000000000000000000000000000000..df02590a6cf3debd7b389b96dead5b31998961c6 --- /dev/null +++ b/pyPDAF/source/src/fortran/pdaf_c_iau.f90 @@ -0,0 +1,111 @@ +MODULE pdaf_c_iau +use iso_c_binding, only: c_int, c_double, c_bool +use PDAF +use pdaf_c_cb_interface + +implicit none + +contains + SUBROUTINE c__PDAF_iau_init(type_iau_in, nsteps_iau_in, flag) bind(c) + ! Type of IAU, (0) no IAU + INTEGER(c_int), INTENT(in) :: type_iau_in + ! number of time steps in IAU + INTEGER(c_int), INTENT(in) :: nsteps_iau_in + ! Status flag + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_iau_init(type_iau_in, nsteps_iau_in, flag) + + END SUBROUTINE c__PDAF_iau_init + + SUBROUTINE c__PDAF_iau_reset(type_iau_in, nsteps_iau_in, flag) bind(c) + ! Type of IAU, (0) no IAU + INTEGER(c_int), INTENT(in) :: type_iau_in + ! number of time steps in IAU + INTEGER(c_int), INTENT(in) :: nsteps_iau_in + ! Status flag + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_iau_reset(type_iau_in, nsteps_iau_in, flag) + + END SUBROUTINE c__PDAF_iau_reset + + SUBROUTINE c__PDAF_iau_set_weights(iweights, weights) bind(c) + ! Length of weights input vector + INTEGER(c_int), INTENT(in) :: iweights + ! Input weight vector + REAL(c_double), DIMENSION(iweights), INTENT(in) :: weights + + + call PDAF_iau_set_weights(iweights, weights) + + END SUBROUTINE c__PDAF_iau_set_weights + + SUBROUTINE c__PDAF_iau_set_pointer(iau_ptr, flag) bind(c) + ! Pointer to IAU ensemble array + REAL(c_double), POINTER, DIMENSION(:,:), INTENT(out) :: iau_ptr + ! Status flag + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_iau_set_pointer(iau_ptr, flag) + END SUBROUTINE c__PDAF_iau_set_pointer + + SUBROUTINE c__PDAF_iau_init_inc(dim_p, dim_ens_l, ens_inc, flag) bind(c) + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! Task-local size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens_l + ! PE-local increment ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens_l), INTENT(in) :: ens_inc + ! Status flag + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_iau_init_inc(dim_p, dim_ens_l, ens_inc, flag) + + END SUBROUTINE c__PDAF_iau_init_inc + + SUBROUTINE c__PDAF_iau_add_inc(u_collect_state, u_distribute_state) bind(c) + use pdaf_c_f_interface, only: collect_state_pdaf_c_ptr, & + distribute_state_pdaf_c_ptr, & + f__collect_state_pdaf, f__distribute_state_pdaf + implicit none + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + + call PDAF_iau_add_inc(f__collect_state_pdaf, f__distribute_state_pdaf) + + END SUBROUTINE c__PDAF_iau_add_inc + + SUBROUTINE c__PDAF_iau_set_ens_pointer(iau_ptr, flag) bind(c) + use PDAF_IAU, only: PDAF_iau_set_ens_pointer + IMPLICIT NONE + !< Pointer to IAU ensemble array + REAL(c_double), POINTER, DIMENSION(:,:), INTENT(out) :: iau_ptr + !< Status flag + INTEGER(c_int), INTENT(out) :: flag + + call PDAF_iau_set_ens_pointer(iau_ptr, flag) + + END SUBROUTINE c__PDAF_iau_set_ens_pointer + + SUBROUTINE c__PDAF_iau_set_state_pointer(iau_x_ptr, flag) bind(c) + use PDAF_IAU, only: PDAF_iau_set_state_pointer + IMPLICIT NONE + !< Pointer to IAU state vector + REAL(c_double), POINTER, DIMENSION(:), INTENT(out) :: iau_x_ptr + !< Status flag + INTEGER(c_int), INTENT(out) :: flag + + call PDAF_iau_set_state_pointer(iau_x_ptr, flag) + + END SUBROUTINE c__PDAF_iau_set_state_pointer +END MODULE pdaf_c_iau \ No newline at end of file diff --git a/pyPDAF/source/src/fortran/pdaf_c_iau_internal.f90 b/pyPDAF/source/src/fortran/pdaf_c_iau_internal.f90 new file mode 100644 index 0000000000000000000000000000000000000000..94b26165143a715257527cee085bd1661bab0646 --- /dev/null +++ b/pyPDAF/source/src/fortran/pdaf_c_iau_internal.f90 @@ -0,0 +1,66 @@ +MODULE pdaf_c_iau_internal +use iso_c_binding, only: c_double, c_int, c_bool +use PDAF +use PDAF_iau +use pdaf_c_cb_interface +implicit none + +contains + SUBROUTINE c__PDAF_iau_init_weights(type_iau, nsteps_iau) bind(c) + ! Type of IAU, (0) no IAU + INTEGER(c_int), INTENT(in) :: type_iau + ! number of time steps in IAU + INTEGER(c_int), INTENT(in) :: nsteps_iau + + + call PDAF_iau_init_weights(type_iau, nsteps_iau) + + END SUBROUTINE c__PDAF_iau_init_weights + + SUBROUTINE c__PDAF_iau_update_inc(ens_ana, state_ana) bind(c) + ! PE-local analysis ensemble + REAL(c_double), DIMENSION(:, :), INTENT(inout) :: ens_ana + ! PE-local state vector + REAL(c_double), DIMENSION(:), INTENT(inout) :: state_ana + + call PDAF_iau_update_inc(ens_ana, state_ana) + + END SUBROUTINE c__PDAF_iau_update_inc + + SUBROUTINE c__PDAF_iau_add_inc_ens(step, dim_p, dim_ens_task, ens, & + state, u_collect_state, u_distribute_state) bind(c) + ! Time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! Ensemble size of model task + INTEGER(c_int), INTENT(in) :: dim_ens_task + ! PE-local state ensemble + REAL(c_double), DIMENSION(:, :), INTENT(inout) :: ens + ! PE-local state vector + REAL(c_double), DIMENSION(:), INTENT(inout) :: state + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + + call PDAF_iau_add_inc_ens(step, dim_p, dim_ens_task, ens, state, & + u_collect_state, u_distribute_state) + + END SUBROUTINE c__PDAF_iau_add_inc_ens + + SUBROUTINE c__PDAF_iau_update_ens(ens, state) bind(c) + ! PE-local state ensemble + REAL(c_double), DIMENSION(:, :), INTENT(inout) :: ens + ! PE-local state vector + REAL(c_double), DIMENSION(:), INTENT(inout) :: state + + call PDAF_iau_update_ens(ens, state) + + END SUBROUTINE c__PDAF_iau_update_ens + + SUBROUTINE c__PDAF_iau_dealloc() bind(c) + call PDAF_iau_dealloc() + END SUBROUTINE c__PDAF_iau_dealloc +END MODULE pdaf_c_iau_internal diff --git a/pyPDAF/source/src/fortran/pdaf_c_internal.f90 b/pyPDAF/source/src/fortran/pdaf_c_internal.f90 new file mode 100644 index 0000000000000000000000000000000000000000..179bf80fc06df7f36034d5d39dc725a6a22ce591 --- /dev/null +++ b/pyPDAF/source/src/fortran/pdaf_c_internal.f90 @@ -0,0 +1,6580 @@ +MODULE pdaf_c_internal +use iso_c_binding, only: c_int, c_double, c_bool, c_char, c_null_char +use pdaf_c_cb_interface +use pdaf_c_f_interface +implicit none + +contains + SUBROUTINE c__PDAF_MPI_init() bind(c) + use PDAF_mod_parallel + call PDAF_MPI_init() + END SUBROUTINE c__PDAF_MPI_init + + SUBROUTINE c__PDAF_timeit(timerID, operation) bind(c) + use PDAF_timer, only: PDAF_timeit + implicit none + !< ID of timer + INTEGER(c_int), INTENT(in) :: timerID + !< Requested operation + CHARACTER(kind=c_char), dimension(*), INTENT(in) :: operation + + CHARACTER(len=3) :: clean_operation + INTEGER :: i + + ! Remove null characters from filterstr + clean_operation = "" + i = 1 + DO WHILE (.true.) + IF (operation(i) == c_null_char) EXIT + clean_operation(i:i) = operation(i) + i = i + 1 + END DO + + call PDAF_timeit(timerID, clean_operation) + END SUBROUTINE c__PDAF_timeit + + SUBROUTINE c__PDAF_set_forget(step, localfilter, dim_obs_p, dim_ens, mens_p, & + mstate_p, obs_p, u_init_obsvar, forget_in, forget_out, screen) bind(c) + use PDAF_analysis_utils + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Whether filter is domain-local + INTEGER(c_int), INTENT(in) :: localfilter + ! Dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! Observed PE-local ensemble + REAL(c_double), DIMENSION(dim_obs_p, dim_ens), INTENT(in) :: mens_p + ! Observed PE-local mean state + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: mstate_p + ! Observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Prescribed forgetting factor + REAL(c_double), INTENT(in) :: forget_in + ! Adaptively estimated forgetting factor + REAL(c_double), INTENT(out) :: forget_out + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + ! Initialize mean obs. error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + + init_obsvar_pdaf_c_ptr => u_init_obsvar + + call PDAF_set_forget(step, localfilter, dim_obs_p, dim_ens, mens_p, & + mstate_p, obs_p, f__init_obsvar_pdaf, forget_in, forget_out, screen) + + END SUBROUTINE c__PDAF_set_forget + + SUBROUTINE c__PDAF_set_iparam_filters(id, value, flag) bind(c) + use PDAF_utils_filters + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + INTEGER(c_int), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_set_iparam_filters(id, value, flag) + + END SUBROUTINE c__PDAF_set_iparam_filters + + SUBROUTINE c__PDAF_set_rparam_filters(id, value, flag) bind(c) + use PDAF_utils_filters + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + REAL(c_double), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_set_rparam_filters(id, value, flag) + + END SUBROUTINE c__PDAF_set_rparam_filters + + SUBROUTINE c__PDAF_set_forget_local(domain, step, dim_obs_l, dim_ens, hx_l, & + hxbar_l, obs_l, u_init_obsvar_l, forget, aforget) bind(c) + use PDAF_analysis_utils + implicit none + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Dimension of local observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! Local observed ensemble + REAL(c_double), DIMENSION(dim_obs_l, dim_ens), INTENT(in) :: hx_l + ! Local observed state estimate + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: hxbar_l + ! Local observation vector + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: obs_l + ! Prescribed forgetting factor + REAL(c_double), INTENT(in) :: forget + ! Adaptive forgetting factor + REAL(c_double), INTENT(out) :: aforget + + ! Initialize local mean obs. error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + + call PDAF_set_forget_local(domain, step, dim_obs_l, dim_ens, hx_l, & + hxbar_l, obs_l, f__init_obsvar_l_pdaf, forget, aforget) + + END SUBROUTINE c__PDAF_set_forget_local + + SUBROUTINE c__PDAF_fcst_operations(step, u_collect_state, & + u_distribute_state, u_init_dim_obs, u_obs_op, u_init_obs, outflag) bind(c) + use PDAF_forecast + implicit none + ! Time step in current forecast phase + INTEGER(c_int), INTENT(in) :: step + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + + call PDAF_fcst_operations(step, f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, outflag) + + END SUBROUTINE c__PDAF_fcst_operations + + SUBROUTINE c__PDAF_letkf_ana_T(domain_p, step, dim_l, dim_obs_l, dim_ens, & + state_l, ainv_l, ens_l, hz_l, hxbar_l, obs_l, rndmat, forget, & + u_prodrinva_l, type_trans, screen, debug, flag) bind(c) + use PDAF_letkf_analysis_T + implicit none + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! State dimension on local analysis domain + INTEGER(c_int), INTENT(in) :: dim_l + ! Size of obs. vector on local ana. domain + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Local forecast state + REAL(c_double), DIMENSION(dim_l), INTENT(inout) :: state_l + ! on exit: local weight matrix for ensemble transformation + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(out) :: ainv_l + ! Local state ensemble + REAL(c_double), DIMENSION(dim_l, dim_ens), INTENT(inout) :: ens_l + ! Local observed state ensemble (perturbation) + REAL(c_double), DIMENSION(dim_obs_l, dim_ens), INTENT(inout) :: hz_l + ! Local observed ensemble mean + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: hxbar_l + ! Local observation vector + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: obs_l + ! Global random rotation matrix + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(inout) :: rndmat + ! Forgetting factor + REAL(c_double), INTENT(inout) :: forget + ! Type of ensemble transformation + INTEGER(c_int), INTENT(in) :: type_trans + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Provide product R^-1 A for local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + + call PDAF_letkf_ana_T(domain_p, step, dim_l, dim_obs_l, dim_ens, state_l, & + ainv_l, ens_l, hz_l, hxbar_l, obs_l, rndmat, forget, f__prodrinva_l_pdaf, & + type_trans, screen, debug, flag) + + END SUBROUTINE c__PDAF_letkf_ana_T + + SUBROUTINE c__PDAFseik_update(step, dim_p, dim_obs_p, dim_ens, rank, & + state_p, uinv, ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_prodrinva, & + u_init_obsvar, u_prepoststep, screen, subtype, flag) bind(c) + use PDAF_seik_update + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: rank + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Inverse of matrix U + REAL(c_double), DIMENSION(rank, rank), INTENT(inout) :: uinv + ! PE-local ensemble matrix + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Filter subtype + INTEGER(c_int), INTENT(in) :: subtype + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A for SEIK analysis + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + call PDAFseik_update(step, dim_p, dim_obs_p, dim_ens, rank, state_p, & + uinv, ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_prodrinva, & + u_init_obsvar, u_prepoststep, screen, subtype, flag) + + END SUBROUTINE c__PDAFseik_update + + SUBROUTINE c__PDAF3dvar_update(step, dim_p, dim_obs_p, dim_ens, dim_cvec, & + state_p, ainv, ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_prodrinva, & + u_prepoststep, u_cvt, u_cvt_adj, u_obs_op_lin, u_obs_op_adj, screen, & + flag) bind(c) + use PDAF_3dvar_update + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Size of control vector (parameterized part) + INTEGER(c_int), INTENT(in) :: dim_cvec + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Not used in 3D-Var + REAL(c_double), DIMENSION(1, 1), INTENT(inout) :: ainv + ! PE-local ensemble matrix + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A for 3DVAR analysis + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Apply control vector transform matrix + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + + call PDAF3dvar_update(step, dim_p, dim_obs_p, dim_ens, dim_cvec, state_p, & + ainv, ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_prodrinva, & + u_prepoststep, u_cvt, u_cvt_adj, u_obs_op_lin, u_obs_op_adj, screen, & + flag) + + END SUBROUTINE c__PDAF3dvar_update + + SUBROUTINE c__PDAFen3dvar_update_estkf(step, dim_p, dim_obs_p, dim_ens, & + dim_cvec_ens, state_p, ainv, ens_p, u_init_dim_obs, u_obs_op, u_init_obs, & + u_prodrinva, u_prepoststep, u_cvt_ens, u_cvt_adj_ens, u_obs_op_lin, & + u_obs_op_adj, u_init_obsvar, screen, flag) bind(c) + use PDAF_en3dvar_update + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Size of control vector (ensemble part) + INTEGER(c_int), INTENT(in) :: dim_cvec_ens + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Transform matrix + REAL(c_double), DIMENSION(dim_ens-1, dim_ens-1), INTENT(inout) :: ainv + ! PE-local ensemble matrix + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A for 3DVAR analysis + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Apply control vector transform matrix (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble var) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + + call PDAFen3dvar_update_estkf(step, dim_p, dim_obs_p, dim_ens, & + dim_cvec_ens, state_p, ainv, ens_p, u_init_dim_obs, u_obs_op, & + u_init_obs, u_prodrinva, u_prepoststep, u_cvt_ens, u_cvt_adj_ens, & + u_obs_op_lin, u_obs_op_adj, u_init_obsvar, screen, flag) + + END SUBROUTINE c__PDAFen3dvar_update_estkf + + SUBROUTINE c__PDAFen3dvar_update_lestkf(step, dim_p, dim_obs_p, dim_ens, & + dim_cvec_ens, state_p, ainv, ens_p, u_init_dim_obs, u_obs_op, u_init_obs, & + u_prodrinva, u_prepoststep, u_cvt_ens, u_cvt_adj_ens, u_obs_op_lin, & + u_obs_op_adj, u_init_dim_obs_f, u_obs_op_f, u_init_obs_f, u_init_obs_l, & + u_prodrinva_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + screen, flag) bind(c) + use PDAF_en3dvar_update + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Size of control vector (ensemble part) + INTEGER(c_int), INTENT(in) :: dim_cvec_ens + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Transform matrix + REAL(c_double), DIMENSION(dim_ens-1, dim_ens-1), INTENT(inout) :: ainv + ! PE-local ensemble matrix + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A for 3DVAR analysis + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Apply control vector transform matrix (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble var) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs_f + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_f + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs_f + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + + call PDAFen3dvar_update_lestkf(step, dim_p, dim_obs_p, dim_ens, & + dim_cvec_ens, state_p, ainv, ens_p, u_init_dim_obs, u_obs_op, & + u_init_obs, u_prodrinva, u_prepoststep, u_cvt_ens, u_cvt_adj_ens, & + u_obs_op_lin, u_obs_op_adj, u_init_dim_obs_f, u_obs_op_f, & + u_init_obs_f, u_init_obs_l, u_prodrinva_l, u_init_n_domains_p, & + u_init_dim_l, u_init_dim_obs_l, u_g2l_state, u_l2g_state, u_g2l_obs, & + u_init_obsvar, u_init_obsvar_l, screen, flag) + + END SUBROUTINE c__PDAFen3dvar_update_lestkf + + SUBROUTINE c__PDAFetkf_update(step, dim_p, dim_obs_p, dim_ens, state_p, & + ainv, ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_prodrinva, & + u_init_obsvar, u_prepoststep, screen, subtype, dim_lag, sens_p, & + cnt_maxlag, flag) bind(c) + use PDAF_etkf_update + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Inverse of matrix U + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(inout) :: ainv + ! PE-local ensemble matrix + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Filter subtype + INTEGER(c_int), INTENT(in) :: subtype + ! Number of past time instances for smoother + INTEGER(c_int), INTENT(in) :: dim_lag + ! PE-local smoother ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens, dim_lag), INTENT(inout) :: sens_p + ! Count number of past time steps for smoothing + INTEGER(c_int), INTENT(inout) :: cnt_maxlag + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A for ETKF analysis + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + call PDAFetkf_update(step, dim_p, dim_obs_p, dim_ens, state_p, ainv, & + ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_prodrinva, & + u_init_obsvar, u_prepoststep, screen, subtype, dim_lag, sens_p, & + cnt_maxlag, flag) + + END SUBROUTINE c__PDAFetkf_update + + SUBROUTINE c__PDAF_netf_ana(step, dim_p, dim_obs_p, dim_ens, state_p, ens_p, & + rndmat, t, type_forget, forget, type_winf, limit_winf, type_noise, & + noise_amp, hz_p, obs_p, u_likelihood, screen, debug, flag) bind(c) + use PDAF_netf_analysis + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local forecast state + REAL(c_double), DIMENSION(dim_p), INTENT(out) :: state_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Orthogonal random matrix + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(in) :: rndmat + ! Ensemble transform matrix + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(inout) :: t + ! Type of forgetting factor + INTEGER(c_int), INTENT(in) :: type_forget + ! Forgetting factor + REAL(c_double), INTENT(in) :: forget + ! Type of weights inflation + INTEGER(c_int), INTENT(in) :: type_winf + ! Limit for weights inflation + REAL(c_double), INTENT(in) :: limit_winf + ! Type of pertubing noise + INTEGER(c_int), INTENT(in) :: type_noise + ! Amplitude of noise + REAL(c_double), INTENT(in) :: noise_amp + ! Temporary matrices for analysis + REAL(c_double), DIMENSION(dim_obs_p, dim_ens), INTENT(in) :: hz_p + ! PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Compute observation likelihood for an ensemble member + procedure(c__likelihood_pdaf) :: u_likelihood + + likelihood_pdaf_c_ptr => u_likelihood + + call PDAF_netf_ana(step, dim_p, dim_obs_p, dim_ens, state_p, ens_p, & + rndmat, t, type_forget, forget, type_winf, limit_winf, type_noise, & + noise_amp, hz_p, obs_p, f__likelihood_pdaf, screen, debug, flag) + + END SUBROUTINE c__PDAF_netf_ana + + SUBROUTINE c__PDAF_netf_smootherT(step, dim_p, dim_obs_p, dim_ens, ens_p, & + rndmat, TA, HX_p, obs_p, u_likelihood, screen, flag) bind(c) + use PDAF_netf_analysis + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Orthogonal random matrix + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(in) :: rndmat + ! Ensemble transform matrix + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(inout) :: TA + !< Temporary matrices for analysis + REAL(c_double), DIMENSION(dim_obs_p, dim_ens), INTENT(in) :: HX_p + !< PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Compute observation likelihood for an ensemble member + procedure(c__likelihood_pdaf) :: u_likelihood + + likelihood_pdaf_c_ptr => u_likelihood + + call PDAF_netf_smootherT(step, dim_p, dim_obs_p, dim_ens, ens_p, rndmat, & + TA, HX_p, obs_p, u_likelihood, screen, flag) + + END SUBROUTINE c__PDAF_netf_smootherT + + SUBROUTINE c__PDAF_smoother_netf(dim_p, dim_ens, dim_lag, ainv, sens_p, & + cnt_maxlag, screen) bind(c) + use PDAF_netf_analysis + implicit none + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Number of past time instances for smoother + INTEGER(c_int), INTENT(in) :: dim_lag + ! Weight matrix for ensemble transformation + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(in) :: ainv + ! PE-local smoother ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens, dim_lag), INTENT(inout) :: sens_p + ! Count available number of time steps for smoothing + INTEGER(c_int), INTENT(inout) :: cnt_maxlag + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + + call PDAF_smoother_netf(dim_p, dim_ens, dim_lag, ainv, sens_p, & + cnt_maxlag, screen) + + END SUBROUTINE c__PDAF_smoother_netf + + SUBROUTINE c__PDAF_lnetf_ana(domain_p, step, dim_l, dim_obs_l, dim_ens, & + ens_l, hx_l, obs_l, rndmat, u_likelihood_l, type_forget, forget, & + type_winf, limit_winf, cnt_small_svals, eff_dimens, t, screen, debug, & + flag) bind(c) + use PDAF_lnetf_analysis + implicit none + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! State dimension on local analysis domain + INTEGER(c_int), INTENT(in) :: dim_l + ! Size of obs. vector on local ana. domain + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Local state ensemble + REAL(c_double), DIMENSION(dim_l, dim_ens), INTENT(inout) :: ens_l + ! Local observed state ensemble (perturbation) + REAL(c_double), DIMENSION(dim_obs_l, dim_ens), INTENT(in) :: hx_l + ! Local observation vector + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: obs_l + ! Global random rotation matrix + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(in) :: rndmat + ! Typ eof forgetting factor + INTEGER(c_int), INTENT(in) :: type_forget + ! Forgetting factor + REAL(c_double), INTENT(in) :: forget + ! Type of weights inflation + INTEGER(c_int), INTENT(in) :: type_winf + ! Limit for weights inflation + REAL(c_double), INTENT(in) :: limit_winf + ! Number of small eigen values + INTEGER(c_int), INTENT(inout) :: cnt_small_svals + ! Effective ensemble size + REAL(c_double), DIMENSION(1), INTENT(inout) :: eff_dimens + ! local ensemble transformation matrix + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(inout) :: t + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Compute observation likelihood for an ensemble member + procedure(c__likelihood_l_pdaf) :: u_likelihood_l + + likelihood_l_pdaf_c_ptr => u_likelihood_l + + call PDAF_lnetf_ana(domain_p, step, dim_l, dim_obs_l, dim_ens, ens_l, & + hx_l, obs_l, rndmat, f__likelihood_l_pdaf, type_forget, forget, type_winf, & + limit_winf, cnt_small_svals, eff_dimens, t, screen, debug, flag) + + END SUBROUTINE c__PDAF_lnetf_ana + + SUBROUTINE c__PDAF_lnetf_smootherT(domain_p, step, dim_obs_f, dim_obs_l, & + dim_ens, hx_f, rndmat, u_g2l_obs, u_init_obs_l, u_likelihood_l, screen, & + t, flag) bind(c) + use PDAF_lnetf_analysis + implicit none + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of full observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_f + ! Size of obs. vector on local ana. domain + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local full observed state ens. + REAL(c_double), DIMENSION(dim_obs_f, dim_ens), INTENT(in) :: hx_f + ! Global random rotation matrix + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(in) :: rndmat + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! local ensemble transformation matrix + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(inout) :: t + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! Compute observation likelihood for an ensemble member + procedure(c__likelihood_l_pdaf) :: u_likelihood_l + + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + likelihood_l_pdaf_c_ptr => u_likelihood_l + + call PDAF_lnetf_smootherT(domain_p, step, dim_obs_f, dim_obs_l, dim_ens, & + hx_f, rndmat, f__g2l_obs_pdaf, f__init_obs_l_pdaf, f__likelihood_l_pdaf, screen, t, flag) + + END SUBROUTINE c__PDAF_lnetf_smootherT + + SUBROUTINE c__PDAF_smoother_lnetf(domain_p, step, dim_p, dim_l, dim_ens, & + dim_lag, ainv, ens_l, sens_p, cnt_maxlag, u_g2l_state, u_l2g_state, & + screen) bind(c) + use PDAF_lnetf_analysis + implicit none + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! State dimension on local analysis domain + INTEGER(c_int), INTENT(in) :: dim_l + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Number of past time instances for smoother + INTEGER(c_int), INTENT(in) :: dim_lag + ! Weight matrix for ensemble transformation + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(in) :: ainv + ! local past ensemble (temporary) + REAL(c_double), DIMENSION(dim_l, dim_ens), INTENT(inout) :: ens_l + ! PE-local smoother ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens, dim_lag), INTENT(inout) :: sens_p + ! Count available number of time steps for smoothing + INTEGER(c_int), INTENT(inout) :: cnt_maxlag + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + ! Get state on local ana. domain from global state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + + call PDAF_smoother_lnetf(domain_p, step, dim_p, dim_l, dim_ens, dim_lag, & + ainv, ens_l, sens_p, cnt_maxlag, f__g2l_state_pdaf, f__l2g_state_pdaf, screen) + + END SUBROUTINE c__PDAF_smoother_lnetf + + SUBROUTINE c__PDAF_memcount_ini(ncounters) bind(c) + use PDAF_memcounting + implicit none + ! Number of memory counters + INTEGER(c_int), INTENT(in) :: ncounters + + + call PDAF_memcount_ini(ncounters) + + END SUBROUTINE c__PDAF_memcount_ini + + SUBROUTINE c__PDAF_memcount_define(stortype, wordlength) bind(c) + use PDAF_memcounting + implicit none + ! Type of variable + CHARACTER(kind=c_char), dimension(*), INTENT(in) :: stortype + ! Word length for chosen type + INTEGER(c_int), INTENT(in) :: wordlength + + call PDAF_memcount_define(stortype(1), wordlength) + + END SUBROUTINE c__PDAF_memcount_define + + SUBROUTINE c__PDAF_memcount(id, stortype, dim) bind(c) + use PDAF_memcounting + implicit none + ! Id of the counter + INTEGER(c_int), INTENT(in) :: id + ! Type of variable + CHARACTER(kind=c_char), dimension(*), INTENT(in) :: stortype + ! Dimension of allocated variable + INTEGER(c_int), INTENT(in) :: dim + + + call PDAF_memcount(id, stortype(1), dim) + + END SUBROUTINE c__PDAF_memcount + + SUBROUTINE c__PDAF_init_filters(type_filter, subtype, param_int, dim_pint, & + param_real, dim_preal, filterstr, ensemblefilter, fixedbasis, screen, & + flag) bind(c) + use PDAF_utils_filters + implicit none + ! Type of filter + INTEGER(c_int), INTENT(in) :: type_filter + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Number of integer parameters + INTEGER(c_int), INTENT(in) :: dim_pint + ! Integer parameter array + INTEGER(c_int), DIMENSION(dim_pint), INTENT(inout) :: param_int + ! Number of real parameters + INTEGER(c_int), INTENT(in) :: dim_preal + ! Real parameter array + REAL(c_double), DIMENSION(dim_preal), INTENT(inout) :: param_real + ! Name of filter algorithm + CHARACTER(kind=c_char), dimension(*), INTENT(out) :: filterstr + ! Is the chosen filter ensemble-based? + LOGICAL(c_bool), INTENT(out) :: ensemblefilter + ! Does the filter run with fixed error-space basis? + LOGICAL(c_bool), INTENT(out) :: fixedbasis + ! Control screen output + INTEGER(c_int), INTENT(in) :: screen + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + logical :: ensemblefilter_out, fixedbasis_out + CHARACTER(len=10) :: local_filterstr ! Local buffer for the string + + call PDAF_init_filters(type_filter, subtype, param_int, dim_pint, & + param_real, dim_preal, local_filterstr, ensemblefilter_out, fixedbasis_out, screen, & + flag) + + ! Copy the string to the output buffer + filterstr(1:len_trim(local_filterstr)+1) = trim(local_filterstr) // c_null_char + + ensemblefilter = ensemblefilter_out + fixedbasis = fixedbasis_out + END SUBROUTINE c__PDAF_init_filters + + SUBROUTINE c__PDAF_alloc_filters(filterstr, subtype, flag) bind(c) + use PDAF_utils_filters + implicit none + ! Name of filter algorithm + CHARACTER(kind=c_char), dimension(*), INTENT(in) :: filterstr + ! Sub-type of filter + INTEGER(c_int), INTENT(in) :: subtype + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + CHARACTER(len=10) :: clean_filterstr + INTEGER :: i + + ! Remove null characters from filterstr + clean_filterstr = "" + i = 1 + DO WHILE (.true.) + IF (filterstr(i) == c_null_char) EXIT + clean_filterstr(i:i) = filterstr(i) + i = i + 1 + END DO + + call PDAF_alloc_filters(clean_filterstr, subtype, flag) + + END SUBROUTINE c__PDAF_alloc_filters + + SUBROUTINE c__PDAF_configinfo_filters(subtype, verbose) bind(c) + use PDAF_utils_filters + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAF_configinfo_filters(subtype, verbose) + + END SUBROUTINE c__PDAF_configinfo_filters + + SUBROUTINE c__PDAF_options_filters(type_filter) bind(c) + use PDAF_utils_filters + implicit none + ! Type of filter + INTEGER(c_int), INTENT(in) :: type_filter + + + call PDAF_options_filters(type_filter) + + END SUBROUTINE c__PDAF_options_filters + + SUBROUTINE c__PDAF_print_info_filters(printtype) bind(c) + use PDAF_utils_filters + implicit none + ! Type of screen output: + INTEGER(c_int), INTENT(in) :: printtype + + + call PDAF_print_info_filters(printtype) + + END SUBROUTINE c__PDAF_print_info_filters + + SUBROUTINE c__PDAF_allreduce(val_p, val_g, mpitype, mpiop, status) bind(c) + use PDAF_comm_obs + implicit none + ! PE-local value + INTEGER(c_int), INTENT(in) :: val_p + ! reduced global value + INTEGER(c_int), INTENT(out) :: val_g + ! MPI data type + INTEGER(c_int), INTENT(in) :: mpitype + ! MPI operator + INTEGER(c_int), INTENT(in) :: mpiop + ! Status flag: (0) no error + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_allreduce(val_p, val_g, mpitype, mpiop, status) + + END SUBROUTINE c__PDAF_allreduce + + SUBROUTINE c__PDAFlseik_update(step, dim_p, dim_obs_f, dim_ens, rank, & + state_p, uinv, ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_init_obs_l, & + u_prodrinva_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + u_prepoststep, screen, subtype, flag) bind(c) + use PDAF_lseik_update + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_f + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: rank + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Inverse of matrix U + REAL(c_double), DIMENSION(rank, rank), INTENT(inout) :: uinv + ! PE-local ensemble matrix + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Filter subtype + INTEGER(c_int), INTENT(in) :: subtype + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! Compute product of R^(-1) with HV + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from global state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + call PDAFlseik_update(step, dim_p, dim_obs_f, dim_ens, rank, state_p, & + uinv, ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_init_obs_l, & + u_prodrinva_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + u_prepoststep, screen, subtype, flag) + + END SUBROUTINE c__PDAFlseik_update + + SUBROUTINE c__PDAF_ensrf_init(subtype, param_int, dim_pint, param_real, & + dim_preal, ensemblefilter, fixedbasis, verbose, outflag) bind(c) + use PDAF_ensrf + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Number of integer parameters + INTEGER(c_int), INTENT(in) :: dim_pint + ! Integer parameter array + INTEGER(c_int), DIMENSION(dim_pint), INTENT(inout) :: param_int + ! Number of real parameters + INTEGER(c_int), INTENT(in) :: dim_preal + ! Real parameter array + REAL(c_double), DIMENSION(dim_preal), INTENT(inout) :: param_real + ! Is the chosen filter ensemble-based? + LOGICAL(c_bool), INTENT(out) :: ensemblefilter + ! Does the filter run with fixed error-space basis? + LOGICAL(c_bool), INTENT(out) :: fixedbasis + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + logical :: ensemblefilter_out, fixedbasis_out + call PDAF_ensrf_init(subtype, param_int, dim_pint, param_real, dim_preal, & + ensemblefilter_out, fixedbasis_out, verbose, outflag) + ensemblefilter = ensemblefilter_out + fixedbasis = fixedbasis_out + END SUBROUTINE c__PDAF_ensrf_init + + SUBROUTINE c__PDAF_ensrf_alloc(outflag) bind(c) + use PDAF_ensrf + implicit none + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + + call PDAF_ensrf_alloc(outflag) + + END SUBROUTINE c__PDAF_ensrf_alloc + + SUBROUTINE c__PDAF_ensrf_config(subtype, verbose) bind(c) + use PDAF_ensrf + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAF_ensrf_config(subtype, verbose) + + END SUBROUTINE c__PDAF_ensrf_config + + SUBROUTINE c__PDAF_ensrf_set_iparam(id, value, flag) bind(c) + use PDAF_ensrf + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + INTEGER(c_int), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_ensrf_set_iparam(id, value, flag) + + END SUBROUTINE c__PDAF_ensrf_set_iparam + + SUBROUTINE c__PDAF_ensrf_set_rparam(id, value, flag) bind(c) + use PDAF_ensrf + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + REAL(c_double), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_ensrf_set_rparam(id, value, flag) + + END SUBROUTINE c__PDAF_ensrf_set_rparam + + SUBROUTINE c__PDAF_ensrf_options() bind(c) + use PDAF_ensrf + implicit none + call PDAF_ensrf_options() + + END SUBROUTINE c__PDAF_ensrf_options + + SUBROUTINE c__PDAF_ensrf_memtime(printtype) bind(c) + use PDAF_ensrf + implicit none + ! Type of screen output: + INTEGER(c_int), INTENT(in) :: printtype + + + call PDAF_ensrf_memtime(printtype) + + END SUBROUTINE c__PDAF_ensrf_memtime + + SUBROUTINE c__PDAF_estkf_ana_fixed(step, dim_p, dim_obs_p, dim_ens, rank, & + state_p, ainv, ens_p, hl_p, hxbar_p, obs_p, forget, u_prodrinva, screen, & + type_sqrt, debug, flag) bind(c) + use PDAF_estkf_analysis_fixed + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: rank + ! on exit: PE-local forecast mean state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Inverse of matrix A - temporary use only + REAL(c_double), DIMENSION(rank, rank), INTENT(inout) :: ainv + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! PE-local observed ensemble + REAL(c_double), DIMENSION(dim_obs_p, dim_ens), INTENT(inout) :: hl_p + ! PE-local observed state + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: hxbar_p + ! PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Forgetting factor + REAL(c_double), INTENT(in) :: forget + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Type of square-root of A + INTEGER(c_int), INTENT(in) :: type_sqrt + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Provide product R^-1 with some matrix + procedure(c__prodrinva_pdaf) :: u_prodrinva + + prodrinva_pdaf_c_ptr => u_prodrinva + + call PDAF_estkf_ana_fixed(step, dim_p, dim_obs_p, dim_ens, rank, state_p, & + ainv, ens_p, hl_p, hxbar_p, obs_p, forget, f__prodrinva_pdaf, screen, & + type_sqrt, debug, flag) + + END SUBROUTINE c__PDAF_estkf_ana_fixed + + SUBROUTINE c__PDAF_etkf_ana_fixed(step, dim_p, dim_obs_p, dim_ens, state_p, & + ainv, ens_p, hz_p, hxbar_p, obs_p, forget, u_prodrinva, screen, debug, & + flag) bind(c) + use PDAF_etkf_analysis_fixed + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! on exit: PE-local forecast state + REAL(c_double), DIMENSION(dim_p), INTENT(out) :: state_p + ! on exit: weight matrix for ensemble transformation + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(out) :: ainv + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! PE-local observed ensemble + REAL(c_double), DIMENSION(dim_obs_p, dim_ens), INTENT(inout) :: hz_p + ! PE-local observed state + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: hxbar_p + ! PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Forgetting factor + REAL(c_double), INTENT(in) :: forget + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + + prodrinva_pdaf_c_ptr => u_prodrinva + + call PDAF_etkf_ana_fixed(step, dim_p, dim_obs_p, dim_ens, state_p, ainv, & + ens_p, hz_p, hxbar_p, obs_p, forget, f__prodrinva_pdaf, screen, debug, flag) + + END SUBROUTINE c__PDAF_etkf_ana_fixed + + SUBROUTINE c__PDAFestkf_update(step, dim_p, dim_obs_p, dim_ens, state_p, & + ainv, ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_prodrinva, & + u_init_obsvar, u_prepoststep, screen, subtype, envar_mode, dim_lag, & + sens_p, cnt_maxlag, flag) bind(c) + use PDAF_estkf_update + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Inverse of transform matrix A + REAL(c_double), DIMENSION(dim_ens-1, dim_ens-1), INTENT(inout) :: ainv + ! PE-local ensemble matrix + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Filter subtype + INTEGER(c_int), INTENT(in) :: subtype + ! Flag whether routine is called from 3DVar for special functionality + INTEGER(c_int), INTENT(in) :: envar_mode + ! Number of past time instances for smoother + INTEGER(c_int), INTENT(in) :: dim_lag + ! PE-local smoother ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens, dim_lag), INTENT(inout) :: sens_p + ! Count number of past time steps for smoothing + INTEGER(c_int), INTENT(inout) :: cnt_maxlag + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A for ESTKF analysis + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + call PDAFestkf_update(step, dim_p, dim_obs_p, dim_ens, state_p, ainv, & + ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_prodrinva, & + u_init_obsvar, u_prepoststep, screen, subtype, envar_mode, dim_lag, & + sens_p, cnt_maxlag, flag) + + END SUBROUTINE c__PDAFestkf_update + + SUBROUTINE c__PDAFlknetf_update_step(step, dim_p, dim_obs_f, dim_ens, & + state_p, ainv, ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_init_obs_l, & + u_prodrinva_hyb_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + u_likelihood_l, u_likelihood_hyb_l, u_prepoststep, screen, subtype, & + flag) bind(c) + use PDAF_lknetf_update_step + + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_f + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Inverse of matrix U + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(inout) :: ainv + ! PE-local ensemble matrix + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Filter subtype + INTEGER(c_int), INTENT(in) :: subtype + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! Compute product of R^(-1) with HV with hybrid weight + procedure(c__prodrinva_hyb_l_pdaf) :: u_prodrinva_hyb_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from global state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! Compute likelihood + procedure(c__likelihood_l_pdaf) :: u_likelihood_l + ! Compute likelihood with hybrid weight + procedure(c__likelihood_hyb_l_pdaf) :: u_likelihood_hyb_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + call PDAFlknetf_update_step(step, dim_p, dim_obs_f, dim_ens, state_p, & + ainv, ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_init_obs_l, & + u_prodrinva_hyb_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + u_likelihood_l, u_likelihood_hyb_l, u_prepoststep, screen, subtype, flag) + + END SUBROUTINE c__PDAFlknetf_update_step + + SUBROUTINE c__PDAFletkf_update(step, dim_p, dim_obs_f, dim_ens, state_p, & + ainv, ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_init_obs_l, & + u_prodrinva_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + u_prepoststep, screen, subtype, dim_lag, sens_p, cnt_maxlag, flag) bind(c) + use PDAF_letkf_update + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_f + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Inverse of matrix U + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(inout) :: ainv + ! PE-local ensemble matrix + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Filter subtype + INTEGER(c_int), INTENT(in) :: subtype + ! Number of past time instances for smoother + INTEGER(c_int), INTENT(in) :: dim_lag + ! PE-local smoother ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens, dim_lag), INTENT(inout) :: sens_p + ! Count number of past time steps for smoothing + INTEGER(c_int), INTENT(inout) :: cnt_maxlag + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + call PDAFletkf_update(step, dim_p, dim_obs_f, dim_ens, state_p, ainv, & + ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_init_obs_l, & + u_prodrinva_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + u_prepoststep, screen, subtype, dim_lag, sens_p, cnt_maxlag, flag) + + END SUBROUTINE c__PDAFletkf_update + + SUBROUTINE c__PDAF_lseik_ana_trans(domain_p, step, dim_l, dim_obs_l, & + dim_ens, rank, state_l, uinv_l, ens_l, hl_l, hxbar_l, obs_l, omegat_in, & + forget, u_prodrinva_l, nm1vsn, type_sqrt, screen, debug, flag) bind(c) + use PDAF_lseik_analysis_trans + implicit none + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! State dimension on local analysis domain + INTEGER(c_int), INTENT(in) :: dim_l + ! Size of obs. vector on local ana. domain + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: rank + ! on exit: state on local analysis domain + REAL(c_double), DIMENSION(dim_l), INTENT(inout) :: state_l + ! Inverse of matrix U - temporary use only + REAL(c_double), DIMENSION(rank, rank), INTENT(inout) :: uinv_l + ! Local state ensemble + REAL(c_double), DIMENSION(dim_l, dim_ens), INTENT(inout) :: ens_l + ! Local observed state ensemble (perturbation) + REAL(c_double), DIMENSION(dim_obs_l, dim_ens), INTENT(inout) :: hl_l + ! Local observed ensemble mean + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: hxbar_l + ! Local observation vector + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: obs_l + ! Matrix Omega + REAL(c_double), DIMENSION(rank, dim_ens), INTENT(inout) :: omegat_in + ! Forgetting factor + REAL(c_double), INTENT(inout) :: forget + ! Whether covariance is normalized with 1/N or 1/(N-1) + INTEGER(c_int), INTENT(in) :: nm1vsn + ! Type of square-root of A + INTEGER(c_int), INTENT(in) :: type_sqrt + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Provide product R^-1 A for local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + + call PDAF_lseik_ana_trans(domain_p, step, dim_l, dim_obs_l, dim_ens, & + rank, state_l, uinv_l, ens_l, hl_l, hxbar_l, obs_l, omegat_in, forget, & + f__prodrinva_l_pdaf, nm1vsn, type_sqrt, screen, debug, flag) + + END SUBROUTINE c__PDAF_lseik_ana_trans + + SUBROUTINE c__PDAF_en3dvar_optim_lbfgs(step, dim_p, dim_ens, dim_cvec_p, & + dim_obs_p, ens_p, obs_p, dy_p, v_p, u_prodrinva, u_cvt_ens, & + u_cvt_adj_ens, u_obs_op_lin, u_obs_op_adj, opt_parallel, screen) bind(c) + use PDAF_en3dvar_optim + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! Size of control vector + INTEGER(c_int), INTENT(in) :: dim_cvec_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(in) :: ens_p + ! Vector of observations + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Background innovation + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: dy_p + ! Control vector + REAL(c_double), DIMENSION(dim_cvec_p), INTENT(inout) :: v_p + ! Whether to use a decomposed control vector + INTEGER(c_int), INTENT(in) :: opt_parallel + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + + call PDAF_en3dvar_optim_lbfgs(step, dim_p, dim_ens, dim_cvec_p, & + dim_obs_p, ens_p, obs_p, dy_p, v_p, f__prodrinva_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, opt_parallel, screen) + + END SUBROUTINE c__PDAF_en3dvar_optim_lbfgs + + SUBROUTINE c__PDAF_en3dvar_optim_cgplus(step, dim_p, dim_ens, dim_cvec_p, & + dim_obs_p, ens_p, obs_p, dy_p, v_p, u_prodrinva, u_cvt_ens, & + u_cvt_adj_ens, u_obs_op_lin, u_obs_op_adj, opt_parallel, screen) bind(c) + use PDAF_en3dvar_optim + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! Size of control vector + INTEGER(c_int), INTENT(in) :: dim_cvec_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(in) :: ens_p + ! Vector of observations + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Background innovation + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: dy_p + ! Control vector + REAL(c_double), DIMENSION(dim_cvec_p), INTENT(inout) :: v_p + ! Whether to use a decomposed control vector + INTEGER(c_int), INTENT(in) :: opt_parallel + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + + call PDAF_en3dvar_optim_cgplus(step, dim_p, dim_ens, dim_cvec_p, & + dim_obs_p, ens_p, obs_p, dy_p, v_p, f__prodrinva_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, opt_parallel, screen) + + END SUBROUTINE c__PDAF_en3dvar_optim_cgplus + + SUBROUTINE c__PDAF_en3dvar_optim_cg(step, dim_p, dim_ens, dim_cvec_p, & + dim_obs_p, ens_p, obs_p, dy_p, v_p, u_prodrinva, u_cvt_ens, & + u_cvt_adj_ens, u_obs_op_lin, u_obs_op_adj, opt_parallel, screen) bind(c) + use PDAF_en3dvar_optim + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! Size of control vector + INTEGER(c_int), INTENT(in) :: dim_cvec_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(in) :: ens_p + ! Vector of observations + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Background innovation + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: dy_p + ! Control vector + REAL(c_double), DIMENSION(dim_cvec_p), INTENT(inout) :: v_p + ! Whether to use a decomposed control vector + INTEGER(c_int), INTENT(in) :: opt_parallel + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + + call PDAF_en3dvar_optim_cg(step, dim_p, dim_ens, dim_cvec_p, dim_obs_p, & + ens_p, obs_p, dy_p, v_p, f__prodrinva_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, opt_parallel, screen) + + END SUBROUTINE c__PDAF_en3dvar_optim_cg + + SUBROUTINE c__PDAF_en3dvar_costf_cvt(step, iter, dim_p, dim_ens, dim_cvec_p, & + dim_obs_p, ens_p, obs_p, dy_p, v_p, j_tot, gradj, u_prodrinva, u_cvt_ens, & + u_cvt_adj_ens, u_obs_op_lin, u_obs_op_adj, opt_parallel) bind(c) + use PDAF_en3dvar_optim + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Optimization iteration + INTEGER(c_int), INTENT(in) :: iter + ! PE-local state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local size of control vector + INTEGER(c_int), INTENT(in) :: dim_cvec_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(in) :: ens_p + ! Vector of observations + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! background innovation + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: dy_p + ! control vector + REAL(c_double), DIMENSION(dim_cvec_p), INTENT(in) :: v_p + ! on exit: Value of cost function + REAL(c_double), INTENT(out) :: j_tot + ! on exit: PE-local gradient of J + REAL(c_double), DIMENSION(dim_cvec_p), INTENT(out) :: gradj + ! Whether to use a decomposed control vector + INTEGER(c_int), INTENT(in) :: opt_parallel + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + + call PDAF_en3dvar_costf_cvt(step, iter, dim_p, dim_ens, dim_cvec_p, & + dim_obs_p, ens_p, obs_p, dy_p, v_p, j_tot, gradj, f__prodrinva_pdaf, & + f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, opt_parallel) + + END SUBROUTINE c__PDAF_en3dvar_costf_cvt + + SUBROUTINE c__PDAF_en3dvar_costf_cg_cvt(step, iter, dim_p, dim_ens, & + dim_cvec_p, dim_obs_p, ens_p, obs_p, dy_p, v_p, d_p, j_tot, gradj, & + hessjd, u_prodrinva, u_cvt_ens, u_cvt_adj_ens, u_obs_op_lin, & + u_obs_op_adj, opt_parallel) bind(c) + use PDAF_en3dvar_optim + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Optimization iteration + INTEGER(c_int), INTENT(in) :: iter + ! PE-local state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local size of control vector + INTEGER(c_int), INTENT(in) :: dim_cvec_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(in) :: ens_p + ! Vector of observations + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Background innovation + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: dy_p + ! Control vector + REAL(c_double), DIMENSION(dim_cvec_p), INTENT(in) :: v_p + ! CG descent direction + REAL(c_double), DIMENSION(dim_cvec_p), INTENT(inout) :: d_p + ! on exit: Value of cost function + REAL(c_double), INTENT(out) :: j_tot + ! on exit: gradient of J + REAL(c_double), DIMENSION(dim_cvec_p), INTENT(out) :: gradj + ! on exit: Hessian of J times d_p + REAL(c_double), DIMENSION(dim_cvec_p), INTENT(out) :: hessjd + ! Whether to use a decomposed control vector + INTEGER(c_int), INTENT(in) :: opt_parallel + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + + call PDAF_en3dvar_costf_cg_cvt(step, iter, dim_p, dim_ens, dim_cvec_p, & + dim_obs_p, ens_p, obs_p, dy_p, v_p, d_p, j_tot, gradj, hessjd, & + f__prodrinva_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + opt_parallel) + + END SUBROUTINE c__PDAF_en3dvar_costf_cg_cvt + + SUBROUTINE c__PDAF_gather_ens(dim_p, dim_ens_p, ens, state, screen) bind(c) + use PDAF_communicate_ens + implicit none + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(:, :), INTENT(inout) :: ens + !< PE-local state vector (for SEEK) + REAL(c_double), DIMENSION(:), INTENT(inout) :: state + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + + call PDAF_gather_ens(dim_p, dim_ens_p, ens, state, screen) + + END SUBROUTINE c__PDAF_gather_ens + + SUBROUTINE c__PDAF_scatter_ens(dim_p, dim_ens_p, ens, state, screen) bind(c) + use PDAF_communicate_ens + implicit none + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(:, :), INTENT(inout) :: ens + ! PE-local state vector (for SEEK) + REAL(c_double), DIMENSION(:), INTENT(inout) :: state + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + + call PDAF_scatter_ens(dim_p, dim_ens_p, ens, state, screen) + + END SUBROUTINE c__PDAF_scatter_ens + + SUBROUTINE c__PDAF_hyb3dvar_optim_lbfgs(step, dim_p, dim_ens, dim_cv_par_p, & + dim_cv_ens_p, dim_obs_p, ens_p, obs_p, dy_p, v_par_p, v_ens_p, & + u_prodrinva, u_cvt, u_cvt_adj, u_cvt_ens, u_cvt_adj_ens, u_obs_op_lin, & + u_obs_op_adj, opt_parallel, beta_3dvar, screen) bind(c) + use PDAF_hyb3dvar_optim + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! Size of control vector (parameterized) + INTEGER(c_int), INTENT(in) :: dim_cv_par_p + ! Size of control vector (ensemble) + INTEGER(c_int), INTENT(in) :: dim_cv_ens_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(in) :: ens_p + ! Vector of observations + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Background innovation + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: dy_p + ! Control vector (parameterized part) + REAL(c_double), DIMENSION(dim_cv_par_p), INTENT(inout) :: v_par_p + ! Control vector (ensemble part) + REAL(c_double), DIMENSION(dim_cv_ens_p), INTENT(inout) :: v_ens_p + ! Whether to use a decomposed control vector + INTEGER(c_int), INTENT(in) :: opt_parallel + ! Hybrid weight + REAL(c_double), INTENT(in) :: beta_3dvar + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector (parameterized) + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix (parameterized) + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Apply control vector transform matrix to control vector (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + + call PDAF_hyb3dvar_optim_lbfgs(step, dim_p, dim_ens, dim_cv_par_p, & + dim_cv_ens_p, dim_obs_p, ens_p, obs_p, dy_p, v_par_p, v_ens_p, & + f__prodrinva_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, opt_parallel, beta_3dvar, screen) + + END SUBROUTINE c__PDAF_hyb3dvar_optim_lbfgs + + SUBROUTINE c__PDAF_hyb3dvar_optim_cgplus(step, dim_p, dim_ens, dim_cv_par_p, & + dim_cv_ens_p, dim_obs_p, ens_p, obs_p, dy_p, v_par_p, v_ens_p, & + u_prodrinva, u_cvt, u_cvt_adj, u_cvt_ens, u_cvt_adj_ens, u_obs_op_lin, & + u_obs_op_adj, opt_parallel, beta_3dvar, screen) bind(c) + use PDAF_hyb3dvar_optim + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! Size of control vector (parameterized) + INTEGER(c_int), INTENT(in) :: dim_cv_par_p + ! Size of control vector (ensemble) + INTEGER(c_int), INTENT(in) :: dim_cv_ens_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(in) :: ens_p + ! Vector of observations + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Background innovation + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: dy_p + ! Control vector (parameterized part) + REAL(c_double), DIMENSION(dim_cv_par_p), INTENT(inout) :: v_par_p + ! Control vector (ensemble part) + REAL(c_double), DIMENSION(dim_cv_ens_p), INTENT(inout) :: v_ens_p + ! Whether to use a decomposed control vector + INTEGER(c_int), INTENT(in) :: opt_parallel + ! Hybrid weight + REAL(c_double), INTENT(in) :: beta_3dvar + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector (parameterized) + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix (parameterized) + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Apply control vector transform matrix to control vector (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + + call PDAF_hyb3dvar_optim_cgplus(step, dim_p, dim_ens, dim_cv_par_p, & + dim_cv_ens_p, dim_obs_p, ens_p, obs_p, dy_p, v_par_p, v_ens_p, & + f__prodrinva_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, opt_parallel, beta_3dvar, screen) + + END SUBROUTINE c__PDAF_hyb3dvar_optim_cgplus + + SUBROUTINE c__PDAF_hyb3dvar_optim_cg(step, dim_p, dim_ens, dim_cv_par_p, & + dim_cv_ens_p, dim_obs_p, ens_p, obs_p, dy_p, v_par_p, v_ens_p, & + u_prodrinva, u_cvt, u_cvt_adj, u_cvt_ens, u_cvt_adj_ens, u_obs_op_lin, & + u_obs_op_adj, opt_parallel, beta_3dvar, screen) bind(c) + use PDAF_hyb3dvar_optim + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! Size of control vector (parameterized) + INTEGER(c_int), INTENT(in) :: dim_cv_par_p + ! Size of control vector (ensemble) + INTEGER(c_int), INTENT(in) :: dim_cv_ens_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(in) :: ens_p + ! Vector of observations + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Background innovation + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: dy_p + ! Control vector (parameterized part) + REAL(c_double), DIMENSION(dim_cv_par_p), INTENT(inout) :: v_par_p + ! Control vector (ensemble part) + REAL(c_double), DIMENSION(dim_cv_ens_p), INTENT(inout) :: v_ens_p + ! Whether to use a decomposed control vector + INTEGER(c_int), INTENT(in) :: opt_parallel + ! Hybrid weight + REAL(c_double), INTENT(in) :: beta_3dvar + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector (parameterized) + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix (parameterized) + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Apply control vector transform matrix to control vector (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + + call PDAF_hyb3dvar_optim_cg(step, dim_p, dim_ens, dim_cv_par_p, & + dim_cv_ens_p, dim_obs_p, ens_p, obs_p, dy_p, v_par_p, v_ens_p, & + f__prodrinva_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, opt_parallel, beta_3dvar, screen) + + END SUBROUTINE c__PDAF_hyb3dvar_optim_cg + + SUBROUTINE c__PDAF_hyb3dvar_costf_cvt(step, iter, dim_p, dim_ens, dim_cv_p, & + dim_cv_par_p, dim_cv_ens_p, dim_obs_p, ens_p, obs_p, dy_p, v_par_p, & + v_ens_p, v_p, j_tot, gradj, u_prodrinva, u_cvt, u_cvt_adj, u_cvt_ens, & + u_cvt_adj_ens, u_obs_op_lin, u_obs_op_adj, opt_parallel, beta) bind(c) + use PDAF_hyb3dvar_optim + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Optimization iteration + INTEGER(c_int), INTENT(in) :: iter + ! PE-local state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! Size of control vector (full) + INTEGER(c_int), INTENT(in) :: dim_cv_p + ! Size of control vector (parameterized part) + INTEGER(c_int), INTENT(in) :: dim_cv_par_p + ! Size of control vector (ensemble part) + INTEGER(c_int), INTENT(in) :: dim_cv_ens_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(in) :: ens_p + ! Vector of observations + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! background innovation + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: dy_p + ! Control vector (parameterized part) + REAL(c_double), DIMENSION(dim_cv_par_p), INTENT(inout) :: v_par_p + ! Control vector (ensemble part) + REAL(c_double), DIMENSION(dim_cv_ens_p), INTENT(inout) :: v_ens_p + ! Control vector (full) + REAL(c_double), DIMENSION(dim_cv_p), INTENT(in) :: v_p + ! on exit: Value of cost function + REAL(c_double), INTENT(out) :: j_tot + ! on exit: PE-local gradient of J (full) + REAL(c_double), DIMENSION(dim_cv_p), INTENT(out) :: gradj + ! Whether to use a decomposed control vector + INTEGER(c_int), INTENT(in) :: opt_parallel + ! Hybrid weight + REAL(c_double), INTENT(in) :: beta + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector (parameterized) + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix (parameterized) + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Apply control vector transform matrix to control vector (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + + call PDAF_hyb3dvar_costf_cvt(step, iter, dim_p, dim_ens, dim_cv_p, & + dim_cv_par_p, dim_cv_ens_p, dim_obs_p, ens_p, obs_p, dy_p, v_par_p, & + v_ens_p, v_p, j_tot, gradj, f__prodrinva_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, opt_parallel, beta) + + END SUBROUTINE c__PDAF_hyb3dvar_costf_cvt + + SUBROUTINE c__PDAF_hyb3dvar_costf_cg_cvt(step, iter, dim_p, dim_ens, & + dim_cv_par_p, dim_cv_ens_p, dim_obs_p, ens_p, obs_p, dy_p, v_par_p, & + v_ens_p, d_par_p, d_ens_p, j_tot, gradj_par, gradj_ens, hessjd_par, & + hessjd_ens, u_prodrinva, u_cvt, u_cvt_adj, u_cvt_ens, u_cvt_adj_ens, & + u_obs_op_lin, u_obs_op_adj, opt_parallel, beta) bind(c) + use PDAF_hyb3dvar_optim + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Optimization iteration + INTEGER(c_int), INTENT(in) :: iter + ! PE-local state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! Size of control vector (parameterized part) + INTEGER(c_int), INTENT(in) :: dim_cv_par_p + ! Size of control vector (ensemble part) + INTEGER(c_int), INTENT(in) :: dim_cv_ens_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(in) :: ens_p + ! Vector of observations + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Background innovation + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: dy_p + ! Control vector (parameterized part) + REAL(c_double), DIMENSION(dim_cv_par_p), INTENT(in) :: v_par_p + ! Control vector (ensemble part) + REAL(c_double), DIMENSION(dim_cv_ens_p), INTENT(in) :: v_ens_p + ! CG descent direction (parameterized part) + REAL(c_double), DIMENSION(dim_cv_par_p), INTENT(inout) :: d_par_p + ! CG descent direction (ensemble part) + REAL(c_double), DIMENSION(dim_cv_ens_p), INTENT(inout) :: d_ens_p + ! on exit: Value of cost function + REAL(c_double), INTENT(out) :: j_tot + ! on exit: gradient of J (parameterized part) + REAL(c_double), DIMENSION(dim_cv_par_p), INTENT(out) :: gradj_par + ! on exit: gradient of J (ensemble part) + REAL(c_double), DIMENSION(dim_cv_ens_p), INTENT(out) :: gradj_ens + ! on exit: Hessian of J times d_p (parameterized part) + REAL(c_double), DIMENSION(dim_cv_par_p), INTENT(out) :: hessjd_par + ! on exit: Hessian of J times d_p (ensemble part) + REAL(c_double), DIMENSION(dim_cv_ens_p), INTENT(out) :: hessjd_ens + ! Whether to use a decomposed control vector + INTEGER(c_int), INTENT(in) :: opt_parallel + ! Hybrid weight + REAL(c_double), INTENT(in) :: beta + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector (parameterized) + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix (parameterized) + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Apply control vector transform matrix to control vector (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + + call PDAF_hyb3dvar_costf_cg_cvt(step, iter, dim_p, dim_ens, dim_cv_par_p, & + dim_cv_ens_p, dim_obs_p, ens_p, obs_p, dy_p, v_par_p, v_ens_p, & + d_par_p, d_ens_p, j_tot, gradj_par, gradj_ens, hessjd_par, hessjd_ens, & + f__prodrinva_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, opt_parallel, beta) + + END SUBROUTINE c__PDAF_hyb3dvar_costf_cg_cvt + + SUBROUTINE c__PDAF_print_version() bind(c) + use PDAF_info + implicit none + call PDAF_print_version() + + END SUBROUTINE c__PDAF_print_version + + SUBROUTINE c__PDAFen3dvar_analysis_cvt(step, dim_p, dim_obs_p, dim_ens, & + dim_cvec_ens, state_p, ens_p, state_inc_p, hxbar_p, obs_p, u_prodrinva, & + u_cvt_ens, u_cvt_adj_ens, u_obs_op_lin, u_obs_op_adj, screen, type_opt, & + debug, flag) bind(c) + use PDAF_en3dvar_analysis_cvt + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Size of control vector + INTEGER(c_int), INTENT(in) :: dim_cvec_ens + ! on exit: PE-local forecast state + REAL(c_double), DIMENSION(dim_p), INTENT(out) :: state_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! PE-local state analysis increment + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_inc_p + ! PE-local observed state + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: hxbar_p + ! PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Type of minimizer for 3DVar + INTEGER(c_int), INTENT(in) :: type_opt + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + + call PDAFen3dvar_analysis_cvt(step, dim_p, dim_obs_p, dim_ens, & + dim_cvec_ens, state_p, ens_p, state_inc_p, hxbar_p, obs_p, & + u_prodrinva, u_cvt_ens, u_cvt_adj_ens, u_obs_op_lin, u_obs_op_adj, & + screen, type_opt, debug, flag) + + END SUBROUTINE c__PDAFen3dvar_analysis_cvt + + SUBROUTINE c__PDAF_sisort(n, veca) bind(c) + use PDAF_diag + implicit none + ! + INTEGER(c_int), INTENT(in) :: n + ! + REAL(c_double), DIMENSION(n), INTENT(inout) :: veca + + + call PDAF_sisort(n, veca) + + END SUBROUTINE c__PDAF_sisort + + ! SUBROUTINE c__PDAF_unbiased_moments_from_summed_residuals(dim_ens, dim_p, & + ! kmax, sum_expo_resid, moments) bind(c) + ! ! number of ensemble members/samples + ! INTEGER(c_int), INTENT(in) :: dim_ens + ! ! local size of the state + ! INTEGER(c_int), INTENT(in) :: dim_p + ! ! maximum order of central moment that is computed, maximum is 4 + ! INTEGER(c_int), INTENT(in) :: kmax + ! ! sum of exponentiated residulals + ! REAL(c_double), DIMENSION(dim_p, kmax), INTENT(in) :: sum_expo_resid + ! ! The columns contain the moments of the ensemble + ! REAL(c_double), DIMENSION(dim_p, kmax), INTENT(inout) :: moments + + + ! call PDAF_unbiased_moments_from_summed_residuals(dim_ens, dim_p, kmax, & + ! sum_expo_resid, moments) + + ! END SUBROUTINE c__PDAF_unbiased_moments_from_summed_residuals + + ! SUBROUTINE c__PDAF_biased_moments_from_summed_residuals(dim_ens, dim_p, & + ! kmax, sum_expo_resid, moments) bind(c) + ! ! number of ensemble members/samples + ! INTEGER(c_int), INTENT(in) :: dim_ens + ! ! local size of the state + ! INTEGER(c_int), INTENT(in) :: dim_p + ! ! maximum order of central moment that is computed, maximum is 4 + ! INTEGER(c_int), INTENT(in) :: kmax + ! ! sum of exponentiated residulals + ! REAL(c_double), DIMENSION(dim_p, kmax), INTENT(in) :: sum_expo_resid + ! ! The columns contain the moments of the ensemble + ! REAL(c_double), DIMENSION(dim_p, kmax), INTENT(inout) :: moments + + + ! call PDAF_biased_moments_from_summed_residuals(dim_ens, dim_p, kmax, & + ! sum_expo_resid, moments) + + ! END SUBROUTINE c__PDAF_biased_moments_from_summed_residuals + + SUBROUTINE c__PDAF_enkf_ana_rlm(step, dim_p, dim_obs_p, dim_obs, dim_ens, rank_ana, & + state_p, ens_p, hzb, hx_p, hxbar_p, obs_p, u_add_obs_err, & + u_init_obs_covar, screen, debug, flag) bind(c) + use PDAF_enkf_analysis_rlm + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + !< Global dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs + ! Size of state ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Rank to be considered for inversion of HPH + INTEGER(c_int), INTENT(in) :: rank_ana + ! PE-local ensemble mean state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Ensemble tranformation matrix + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(inout) :: hzb + ! PE-local observed ensemble + REAL(c_double), DIMENSION(dim_obs_p, dim_ens), INTENT(in) :: hx_p + ! PE-local observed state + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: hxbar_p + ! PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Add observation error covariance matrix + procedure(c__add_obs_err_pdaf) :: u_add_obs_err + ! Initialize observation error covariance matrix + procedure(c__init_obs_covar_pdaf) :: u_init_obs_covar + + add_obs_err_pdaf_c_ptr => u_add_obs_err + init_obs_covar_pdaf_c_ptr => u_init_obs_covar + + call PDAF_enkf_ana_rlm(step, dim_p, dim_obs_p, dim_obs, dim_ens, rank_ana, & + state_p, ens_p, hzb, hx_p, hxbar_p, obs_p, f__add_obs_err_pdaf, & + f__init_obs_covar_pdaf, screen, debug, flag) + + END SUBROUTINE c__PDAF_enkf_ana_rlm + + SUBROUTINE c__PDAF_smoother_enkf(dim_p, dim_ens, dim_lag, ainv, sens_p, & + cnt_maxlag, forget, screen) bind(c) + use PDAF_enkf_analysis_rlm + implicit none + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Number of past time instances for smoother + INTEGER(c_int), INTENT(in) :: dim_lag + ! Weight matrix for ensemble transformation + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(in) :: ainv + ! PE-local smoother ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens, dim_lag), INTENT(inout) :: sens_p + ! Count available number of time steps for smoothing + INTEGER(c_int), INTENT(inout) :: cnt_maxlag + ! Forgetting factor + REAL(c_double), INTENT(in) :: forget + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + + call PDAF_smoother_enkf(dim_p, dim_ens, dim_lag, ainv, sens_p, & + cnt_maxlag, forget, screen) + + END SUBROUTINE c__PDAF_smoother_enkf + + SUBROUTINE c__PDAFensrf_update(step, dim_p, dim_obs_p, dim_ens, state_p, & + ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_init_obsvars, & + u_localize_covar_serial, u_prepoststep, screen, subtype, flag) bind(c) + use PDAF_ensrf_update + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_p + ! Size of state ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Specification of filter subtype + INTEGER(c_int), INTENT(in) :: subtype + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Initialize vector of observation error variances + procedure(c__init_obsvar_pdaf) :: u_init_obsvars + ! Apply localization for single-observation vectors + procedure(c__localize_covar_serial_pdaf) :: u_localize_covar_serial + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + call PDAFensrf_update(step, dim_p, dim_obs_p, dim_ens, state_p, ens_p, & + u_init_dim_obs, u_obs_op, u_init_obs, u_init_obsvars, & + u_localize_covar_serial, u_prepoststep, screen, subtype, flag) + + END SUBROUTINE c__PDAFensrf_update + + SUBROUTINE c__PDAF_pf_ana(step, dim_p, dim_obs_p, dim_ens, state_p, ens_p, & + type_resample, type_winf, limit_winf, type_noise, noise_amp, hz_p, obs_p, & + u_likelihood, screen, debug, flag) bind(c) + use PDAF_pf_analysis + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local forecast mean state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Type of resampling scheme + INTEGER(c_int), INTENT(in) :: type_resample + ! Type of weights inflation + INTEGER(c_int), INTENT(in) :: type_winf + ! Limit for weights inflation + REAL(c_double), INTENT(in) :: limit_winf + ! Type of pertubing noise + INTEGER(c_int), INTENT(in) :: type_noise + ! Amplitude of noise + REAL(c_double), INTENT(in) :: noise_amp + ! Temporary matrices for analysis + REAL(c_double), DIMENSION(dim_obs_p, dim_ens), INTENT(in) :: hz_p + ! PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Compute observation likelihood for an ensemble member + procedure(c__likelihood_pdaf) :: u_likelihood + + likelihood_pdaf_c_ptr => u_likelihood + + call PDAF_pf_ana(step, dim_p, dim_obs_p, dim_ens, state_p, ens_p, & + type_resample, type_winf, limit_winf, type_noise, noise_amp, hz_p, & + obs_p, f__likelihood_pdaf, screen, debug, flag) + + END SUBROUTINE c__PDAF_pf_ana + + SUBROUTINE c__PDAF_pf_resampling(method, nin, nout, weights, ids, & + screen) bind(c) + use PDAF_pf_analysis + implicit none + ! Choose resampling method + INTEGER(c_int), INTENT(in) :: method + ! number of particles + INTEGER(c_int), INTENT(in) :: nin + ! number of particles to be resampled + INTEGER(c_int), INTENT(in) :: nout + ! Weights + REAL(c_double), DIMENSION(Nin), INTENT(in) :: weights + ! Indices of resampled ensmeble states + INTEGER(c_int), DIMENSION(Nout), INTENT(out) :: ids + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + + call PDAF_pf_resampling(method, nin, nout, weights, ids, screen) + + END SUBROUTINE c__PDAF_pf_resampling + + SUBROUTINE c__PDAF_mvnormalize(mode, dim_state, dim_field, offset, ncol, & + states, stddev, status) bind(c) + use PDAF_sample + implicit none + ! Mode: (1) normalize, (2) re-scale + INTEGER(c_int), INTENT(in) :: mode + ! Dimension of state vector + INTEGER(c_int), INTENT(in) :: dim_state + ! Dimension of a field in state vector + INTEGER(c_int), INTENT(in) :: dim_field + ! Offset of field in state vector + INTEGER(c_int), INTENT(in) :: offset + ! Number of columns in array states + INTEGER(c_int), INTENT(in) :: ncol + ! State vector array + REAL(c_double), DIMENSION(dim_state, ncol), INTENT(inout) :: states + ! Standard deviation of field + REAL(c_double), INTENT(inout) :: stddev + ! Status flag (0=success) + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_mvnormalize(mode, dim_state, dim_field, offset, ncol, states, & + stddev, status) + + END SUBROUTINE c__PDAF_mvnormalize + + SUBROUTINE c__PDAF_3dvar_init(subtype, param_int, dim_pint, param_real, & + dim_preal, ensemblefilter, fixedbasis, verbose, outflag) bind(c) + use PDAF_3dvar + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Number of integer parameters + INTEGER(c_int), INTENT(in) :: dim_pint + ! Integer parameter array + INTEGER(c_int), DIMENSION(dim_pint), INTENT(inout) :: param_int + ! Number of real parameters + INTEGER(c_int), INTENT(in) :: dim_preal + ! Real parameter array + REAL(c_double), DIMENSION(dim_preal), INTENT(inout) :: param_real + ! Is the chosen filter ensemble-based? + LOGICAL(c_bool), INTENT(out) :: ensemblefilter + ! Does the filter run with fixed error-space basis? + LOGICAL(c_bool), INTENT(out) :: fixedbasis + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + logical :: ensemblefilter_out, fixedbasis_out + call PDAF_3dvar_init(subtype, param_int, dim_pint, param_real, dim_preal, & + ensemblefilter_out, fixedbasis_out, verbose, outflag) + ensemblefilter = ensemblefilter_out + fixedbasis = fixedbasis_out + END SUBROUTINE c__PDAF_3dvar_init + + SUBROUTINE c__PDAF_3dvar_alloc(subtype, outflag) bind(c) + use PDAF_3dvar + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(in) :: subtype + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + + call PDAF_3dvar_alloc(subtype, outflag) + + END SUBROUTINE c__PDAF_3dvar_alloc + + SUBROUTINE c__PDAF_3dvar_config(subtype, verbose) bind(c) + use PDAF_3dvar + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAF_3dvar_config(subtype, verbose) + + END SUBROUTINE c__PDAF_3dvar_config + + SUBROUTINE c__PDAF_3dvar_set_iparam(id, value, flag) bind(c) + use PDAF_3dvar + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + INTEGER(c_int), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_3dvar_set_iparam(id, value, flag) + + END SUBROUTINE c__PDAF_3dvar_set_iparam + + SUBROUTINE c__PDAF_3dvar_set_rparam(id, value, flag) bind(c) + use PDAF_3dvar + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + REAL(c_double), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_3dvar_set_rparam(id, value, flag) + + END SUBROUTINE c__PDAF_3dvar_set_rparam + + SUBROUTINE c__PDAF_3dvar_options() bind(c) + use PDAF_3dvar + implicit none + call PDAF_3dvar_options() + + END SUBROUTINE c__PDAF_3dvar_options + + SUBROUTINE c__PDAF_3dvar_memtime(printtype) bind(c) + use PDAF_3dvar + implicit none + ! Type of screen output: + INTEGER(c_int), INTENT(in) :: printtype + + + call PDAF_3dvar_memtime(printtype) + + END SUBROUTINE c__PDAF_3dvar_memtime + + + SUBROUTINE c__PDAF_reset_dim_ens(dim_ens_in, outflag) bind(c) + use PDAF_set + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(in) :: dim_ens_in + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + + call PDAF_reset_dim_ens(dim_ens_in, outflag) + + END SUBROUTINE c__PDAF_reset_dim_ens + + SUBROUTINE c__PDAF_reset_dim_p(dim_p_in, outflag) bind(c) + use PDAF_set + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(in) :: dim_p_in + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + + call PDAF_reset_dim_p(dim_p_in, outflag) + + END SUBROUTINE c__PDAF_reset_dim_p + + SUBROUTINE c__PDAF_3dvar_optim_lbfgs(step, dim_p, dim_cvec_p, dim_obs_p, & + obs_p, dy_p, v_p, u_prodrinva, u_cvt, u_cvt_adj, u_obs_op_lin, & + u_obs_op_adj, opt_parallel, screen) bind(c) + use PDAF_3dvar_optim + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! Size of control vector + INTEGER(c_int), INTENT(in) :: dim_cvec_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Vector of observations + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Background innovation + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: dy_p + ! Control vector + REAL(c_double), DIMENSION(dim_cvec_p), INTENT(inout) :: v_p + ! Whether to use a decomposed control vector + INTEGER(c_int), INTENT(in) :: opt_parallel + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + + call PDAF_3dvar_optim_lbfgs(step, dim_p, dim_cvec_p, dim_obs_p, obs_p, & + dy_p, v_p, f__prodrinva_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + opt_parallel, screen) + + END SUBROUTINE c__PDAF_3dvar_optim_lbfgs + + SUBROUTINE c__PDAF_3dvar_optim_cgplus(step, dim_p, dim_cvec_p, dim_obs_p, & + obs_p, dy_p, v_p, u_prodrinva, u_cvt, u_cvt_adj, u_obs_op_lin, & + u_obs_op_adj, opt_parallel, screen) bind(c) + use PDAF_3dvar_optim + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! Size of control vector + INTEGER(c_int), INTENT(in) :: dim_cvec_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Vector of observations + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Background innovation + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: dy_p + ! Control vector + REAL(c_double), DIMENSION(dim_cvec_p), INTENT(inout) :: v_p + ! Whether to use a decomposed control vector + INTEGER(c_int), INTENT(in) :: opt_parallel + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + + call PDAF_3dvar_optim_cgplus(step, dim_p, dim_cvec_p, dim_obs_p, obs_p, & + dy_p, v_p, f__prodrinva_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + opt_parallel, screen) + + END SUBROUTINE c__PDAF_3dvar_optim_cgplus + + SUBROUTINE c__PDAF_3dvar_optim_cg(step, dim_p, dim_cvec_p, dim_obs_p, obs_p, & + dy_p, v_p, u_prodrinva, u_cvt, u_cvt_adj, u_obs_op_lin, u_obs_op_adj, & + opt_parallel, screen) bind(c) + use PDAF_3dvar_optim + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! Size of control vector + INTEGER(c_int), INTENT(in) :: dim_cvec_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Vector of observations + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Background innovation + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: dy_p + ! Control vector + REAL(c_double), DIMENSION(dim_cvec_p), INTENT(inout) :: v_p + ! Whether to use a decomposed control vector + INTEGER(c_int), INTENT(in) :: opt_parallel + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + + call PDAF_3dvar_optim_cg(step, dim_p, dim_cvec_p, dim_obs_p, obs_p, dy_p, & + v_p, f__prodrinva_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + opt_parallel, screen) + + END SUBROUTINE c__PDAF_3dvar_optim_cg + + SUBROUTINE c__PDAF_3dvar_costf_cvt(step, iter, dim_p, dim_cvec_p, dim_obs_p, & + obs_p, dy_p, v_p, j_tot, gradj, u_prodrinva, u_cvt, u_cvt_adj, & + u_obs_op_lin, u_obs_op_adj, opt_parallel) bind(c) + use PDAF_3dvar_optim + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Optimization iteration + INTEGER(c_int), INTENT(in) :: iter + ! PE-local state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local size of control vector + INTEGER(c_int), INTENT(in) :: dim_cvec_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Vector of observations + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! background innovation + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: dy_p + ! control vector + REAL(c_double), DIMENSION(dim_cvec_p), INTENT(in) :: v_p + ! on exit: Value of cost function + REAL(c_double), INTENT(out) :: j_tot + ! on exit: PE-local gradient of J + REAL(c_double), DIMENSION(dim_cvec_p), INTENT(out) :: gradj + ! Whether to use a decomposed control vector + INTEGER(c_int), INTENT(in) :: opt_parallel + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + + call PDAF_3dvar_costf_cvt(step, iter, dim_p, dim_cvec_p, dim_obs_p, & + obs_p, dy_p, v_p, j_tot, gradj, f__prodrinva_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, opt_parallel) + + END SUBROUTINE c__PDAF_3dvar_costf_cvt + + SUBROUTINE c__PDAF_3dvar_costf_cg_cvt(step, iter, dim_p, dim_cvec_p, & + dim_obs_p, obs_p, dy_p, v_p, d_p, j_tot, gradj, hessjd, u_prodrinva, & + u_cvt, u_cvt_adj, u_obs_op_lin, u_obs_op_adj, opt_parallel) bind(c) + use PDAF_3dvar_optim + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! CG iteration + INTEGER(c_int), INTENT(in) :: iter + ! PE-local state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local size of control vector + INTEGER(c_int), INTENT(in) :: dim_cvec_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Vector of observations + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Background innovation + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: dy_p + ! Control vector + REAL(c_double), DIMENSION(dim_cvec_p), INTENT(in) :: v_p + ! CG descent direction + REAL(c_double), DIMENSION(dim_cvec_p), INTENT(inout) :: d_p + ! on exit: Value of cost function + REAL(c_double), INTENT(out) :: j_tot + ! on exit: gradient of J + REAL(c_double), DIMENSION(dim_cvec_p), INTENT(out) :: gradj + ! on exit: Hessian of J times d_p + REAL(c_double), DIMENSION(dim_cvec_p), INTENT(out) :: hessjd + ! Whether to use a decomposed control vector + INTEGER(c_int), INTENT(in) :: opt_parallel + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + + call PDAF_3dvar_costf_cg_cvt(step, iter, dim_p, dim_cvec_p, dim_obs_p, & + obs_p, dy_p, v_p, d_p, j_tot, gradj, hessjd, f__prodrinva_pdaf, f__cvt_pdaf, & + f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, opt_parallel) + + END SUBROUTINE c__PDAF_3dvar_costf_cg_cvt + + SUBROUTINE c__PDAF_lknetf_analysis_T(domain_p, step, dim_l, dim_obs_l, & + dim_ens, state_l, ainv_l, ens_l, hx_l, hxbar_l, obs_l, rndmat, forget, & + u_prodrinva_l, u_init_obsvar_l, u_likelihood_l, screen, type_forget, & + eff_dimens, type_hyb, hyb_g, hyb_k, gamma, skew_mabs, kurt_mabs, & + flag) bind(c) + use PDAF_lknetf_analysis_sync + implicit none + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! State dimension on local analysis domain + INTEGER(c_int), INTENT(in) :: dim_l + ! Size of obs. vector on local ana. domain + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! local forecast state + REAL(c_double), DIMENSION(dim_l), INTENT(inout) :: state_l + ! on exit: local weight matrix for ensemble transformation + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(out) :: ainv_l + ! Local state ensemble + REAL(c_double), DIMENSION(dim_l, dim_ens), INTENT(inout) :: ens_l + ! local observed state ens. + REAL(c_double), DIMENSION(dim_obs_l, dim_ens), INTENT(in) :: hx_l + ! local observed ens. mean + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: hxbar_l + ! Local observation vector + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: obs_l + ! Global random rotation matrix + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(inout) :: rndmat + ! Forgetting factor + REAL(c_double), INTENT(inout) :: forget + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Type of forgetting factor + INTEGER(c_int), INTENT(in) :: type_forget + ! Effective ensemble size + REAL(c_double), DIMENSION(1), INTENT(inout) :: eff_dimens + ! Type of hybrid weight + INTEGER(c_int), INTENT(in) :: type_hyb + ! Prescribed hybrid weight for state transformation + REAL(c_double), INTENT(in) :: hyb_g + ! Scale factor kappa (for type_hyb 3 and 4) + REAL(c_double), INTENT(in) :: hyb_k + ! Hybrid weight for state transformation + REAL(c_double), DIMENSION(1), INTENT(inout) :: gamma + ! Mean absolute skewness + REAL(c_double), DIMENSION(1), INTENT(inout) :: skew_mabs + ! Mean absolute kurtosis + REAL(c_double), DIMENSION(1), INTENT(inout) :: kurt_mabs + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Provide product R^-1 A for local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! Provide likelihood of an ensemble state + procedure(c__likelihood_l_pdaf) :: u_likelihood_l + + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + likelihood_l_pdaf_c_ptr => u_likelihood_l + + call PDAF_lknetf_analysis_T(domain_p, step, dim_l, dim_obs_l, dim_ens, & + state_l, ainv_l, ens_l, hx_l, hxbar_l, obs_l, rndmat, forget, & + f__prodrinva_l_pdaf, f__init_obsvar_l_pdaf, f__likelihood_l_pdaf, screen, type_forget, & + eff_dimens, type_hyb, hyb_g, hyb_k, gamma, skew_mabs, kurt_mabs, flag) + + END SUBROUTINE c__PDAF_lknetf_analysis_T + + SUBROUTINE c__PDAF_get_ensstats(skew_ptr, kurt_ptr, status) bind(c) + use PDAF_get + implicit none + ! Pointer to skewness array + REAL(c_double), POINTER, DIMENSION(:), INTENT(out) :: skew_ptr + ! Pointer to kurtosis array + REAL(c_double), POINTER, DIMENSION(:), INTENT(out) :: kurt_ptr + ! Status flag + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_get_ensstats(skew_ptr, kurt_ptr, status) + END SUBROUTINE c__PDAF_get_ensstats + + SUBROUTINE c__PDAF_estkf_init(subtype, param_int, dim_pint, param_real, & + dim_preal, ensemblefilter, fixedbasis, verbose, outflag) bind(c) + use PDAF_estkf + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Number of integer parameters + INTEGER(c_int), INTENT(in) :: dim_pint + ! Integer parameter array + INTEGER(c_int), DIMENSION(dim_pint), INTENT(inout) :: param_int + ! Number of real parameters + INTEGER(c_int), INTENT(in) :: dim_preal + ! Real parameter array + REAL(c_double), DIMENSION(dim_preal), INTENT(inout) :: param_real + ! Is the chosen filter ensemble-based? + LOGICAL(c_bool), INTENT(out) :: ensemblefilter + ! Does the filter run with fixed error-space basis? + LOGICAL(c_bool), INTENT(out) :: fixedbasis + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + logical :: ensemblefilter_out, fixedbasis_out + call PDAF_estkf_init(subtype, param_int, dim_pint, param_real, dim_preal, & + ensemblefilter_out, fixedbasis_out, verbose, outflag) + ensemblefilter = ensemblefilter_out + fixedbasis = fixedbasis_out + END SUBROUTINE c__PDAF_estkf_init + + SUBROUTINE c__PDAF_estkf_alloc(outflag) bind(c) + use PDAF_estkf + implicit none + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + + call PDAF_estkf_alloc(outflag) + + END SUBROUTINE c__PDAF_estkf_alloc + + SUBROUTINE c__PDAF_estkf_config(subtype, verbose) bind(c) + use PDAF_estkf + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAF_estkf_config(subtype, verbose) + + END SUBROUTINE c__PDAF_estkf_config + + SUBROUTINE c__PDAF_estkf_set_iparam(id, value, flag) bind(c) + use PDAF_estkf + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + INTEGER(c_int), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_estkf_set_iparam(id, value, flag) + + END SUBROUTINE c__PDAF_estkf_set_iparam + + SUBROUTINE c__PDAF_estkf_set_rparam(id, value, flag) bind(c) + use PDAF_estkf + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + REAL(c_double), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_estkf_set_rparam(id, value, flag) + + END SUBROUTINE c__PDAF_estkf_set_rparam + + SUBROUTINE c__PDAF_estkf_options() bind(c) + use PDAF_estkf + implicit none + call PDAF_estkf_options() + + END SUBROUTINE c__PDAF_estkf_options + + SUBROUTINE c__PDAF_estkf_memtime(printtype) bind(c) + use PDAF_estkf + implicit none + ! Type of screen output: + INTEGER(c_int), INTENT(in) :: printtype + + + call PDAF_estkf_memtime(printtype) + + END SUBROUTINE c__PDAF_estkf_memtime + + SUBROUTINE c__PDAF_gen_obs(step, dim_p, dim_obs_f, dim_ens, state_p, ainv, & + ens_p, u_init_dim_obs_f, u_obs_op_f, u_get_obs_f, u_init_obserr_f, & + u_prepoststep, screen, flag) bind(c) + use PDAF_generate_obs_update + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_f + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Inverse of matrix U + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(inout) :: ainv + ! PE-local ensemble matrix + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs_f + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_f + ! Provide observation vector to user + procedure(c__get_obs_f_pdaf) :: u_get_obs_f + ! Initialize vector of observation error standard deviations + procedure(c__init_obserr_f_pdaf) :: u_init_obserr_f + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + init_dim_obs_f_pdaf_c_ptr => u_init_dim_obs_f + obs_op_f_pdaf_c_ptr => u_obs_op_f + get_obs_f_pdaf_c_ptr => u_get_obs_f + init_obserr_f_pdaf_c_ptr => u_init_obserr_f + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAF_gen_obs(step, dim_p, dim_obs_f, dim_ens, state_p, ainv, ens_p, & + f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, f__get_obs_f_pdaf, f__init_obserr_f_pdaf, & + f__prepoststep_pdaf, screen, flag) + + END SUBROUTINE c__PDAF_gen_obs + + SUBROUTINE c__PDAFobs_init(step, dim_p, dim_ens, dim_obs_p, state_p, ens_p, & + u_init_dim_obs, u_obs_op, u_init_obs, screen, debug, do_ens_mean, & + do_init_dim, do_hx, do_hxbar, do_init_obs) bind(c) + use PDAFobs + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(inout) :: dim_obs_p + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! PE-local ensemble matrix + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Whether to compute ensemble mean + LOGICAL(c_bool), INTENT(in) :: do_ens_mean + ! Whether to call U_init_dim_obs + LOGICAL(c_bool), INTENT(in) :: do_init_dim + ! Whether to initialize HX_p + LOGICAL(c_bool), INTENT(in) :: do_hx + ! Whether to initialize HXbar + LOGICAL(c_bool), INTENT(in) :: do_hxbar + ! Whether to initialize obs_p + LOGICAL(c_bool), INTENT(in) :: do_init_obs + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + + call PDAFobs_init(step, dim_p, dim_ens, dim_obs_p, state_p, ens_p, & + u_init_dim_obs, u_obs_op, u_init_obs, screen, debug, logical(do_ens_mean), & + logical(do_init_dim), logical(do_hx), logical(do_hxbar), & + logical(do_init_obs)) + + END SUBROUTINE c__PDAFobs_init + + SUBROUTINE c__PDAFobs_init_local(domain_p, step, dim_obs_l, dim_obs_f, & + dim_ens, u_init_dim_obs_l, u_g2l_obs, u_init_obs_l, debug) bind(c) + use PDAFobs + implicit none + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Size of local observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_l + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_f + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + + ! Init. dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + + call PDAFobs_init_local(domain_p, step, dim_obs_l, dim_obs_f, dim_ens, & + u_init_dim_obs_l, u_g2l_obs, u_init_obs_l, debug) + + END SUBROUTINE c__PDAFobs_init_local + + SUBROUTINE c__PDAFobs_init_obsvars(step, dim_obs_p, u_init_obsvars) bind(c) + use PDAFobs + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + + ! Initialize vector of observation error variances + procedure(c__init_obsvars_pdaf) :: u_init_obsvars + + call PDAFobs_init_obsvars(step, dim_obs_p, u_init_obsvars) + + END SUBROUTINE c__PDAFobs_init_obsvars + + SUBROUTINE c__PDAFobs_dealloc() bind(c) + use PDAFobs + implicit none + call PDAFobs_dealloc() + + END SUBROUTINE c__PDAFobs_dealloc + + SUBROUTINE c__PDAFobs_dealloc_local() bind(c) + use PDAFobs + implicit none + call PDAFobs_dealloc_local() + + END SUBROUTINE c__PDAFobs_dealloc_local + + SUBROUTINE c__PDAF_NETF_init(subtype, param_int, dim_pint, param_real, & + dim_preal, ensemblefilter, fixedbasis, verbose, outflag) bind(c) + use PDAF_NETF + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Number of integer parameters + INTEGER(c_int), INTENT(in) :: dim_pint + ! Integer parameter array + INTEGER(c_int), DIMENSION(dim_pint), INTENT(inout) :: param_int + ! Number of real parameters + INTEGER(c_int), INTENT(in) :: dim_preal + ! Real parameter array + REAL(c_double), DIMENSION(dim_preal), INTENT(inout) :: param_real + ! Is the chosen filter ensemble-based? + LOGICAL(c_bool), INTENT(out) :: ensemblefilter + ! Does the filter run with fixed error-space basis? + LOGICAL(c_bool), INTENT(out) :: fixedbasis + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + logical :: ensemblefilter_out, fixedbasis_out + call PDAF_NETF_init(subtype, param_int, dim_pint, param_real, dim_preal, & + ensemblefilter_out, fixedbasis_out, verbose, outflag) + ensemblefilter = ensemblefilter_out + fixedbasis = fixedbasis_out + END SUBROUTINE c__PDAF_NETF_init + + SUBROUTINE c__PDAF_netf_alloc(outflag) bind(c) + use PDAF_NETF + implicit none + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + + call PDAF_netf_alloc(outflag) + + END SUBROUTINE c__PDAF_netf_alloc + + SUBROUTINE c__PDAF_netf_config(subtype, verbose) bind(c) + use PDAF_NETF + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAF_netf_config(subtype, verbose) + + END SUBROUTINE c__PDAF_netf_config + + SUBROUTINE c__PDAF_netf_set_iparam(id, value, flag) bind(c) + use PDAF_NETF + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + INTEGER(c_int), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_netf_set_iparam(id, value, flag) + + END SUBROUTINE c__PDAF_netf_set_iparam + + SUBROUTINE c__PDAF_netf_set_rparam(id, value, flag) bind(c) + use PDAF_NETF + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + REAL(c_double), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_netf_set_rparam(id, value, flag) + + END SUBROUTINE c__PDAF_netf_set_rparam + + SUBROUTINE c__PDAF_netf_options() bind(c) + use PDAF_NETF + implicit none + call PDAF_netf_options() + + END SUBROUTINE c__PDAF_netf_options + + SUBROUTINE c__PDAF_netf_memtime(printtype) bind(c) + use PDAF_NETF + implicit none + ! Type of screen output: + INTEGER(c_int), INTENT(in) :: printtype + + + call PDAF_netf_memtime(printtype) + + END SUBROUTINE c__PDAF_netf_memtime + + SUBROUTINE c__PDAF_lenkf_init(subtype, param_int, dim_pint, param_real, & + dim_preal, ensemblefilter, fixedbasis, verbose, outflag) bind(c) + use PDAF_lenkf + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Number of integer parameters + INTEGER(c_int), INTENT(in) :: dim_pint + ! Integer parameter array + INTEGER(c_int), DIMENSION(dim_pint), INTENT(inout) :: param_int + ! Number of real parameters + INTEGER(c_int), INTENT(in) :: dim_preal + ! Real parameter array + REAL(c_double), DIMENSION(dim_preal), INTENT(inout) :: param_real + ! Is the chosen filter ensemble-based? + LOGICAL(c_bool), INTENT(out) :: ensemblefilter + ! Does the filter run with fixed error-space basis? + LOGICAL(c_bool), INTENT(out) :: fixedbasis + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + logical :: ensemblefilter_out, fixedbasis_out + + call PDAF_lenkf_init(subtype, param_int, dim_pint, param_real, dim_preal, & + ensemblefilter_out, fixedbasis_out, verbose, outflag) + ensemblefilter = ensemblefilter_out + fixedbasis = fixedbasis_out + + END SUBROUTINE c__PDAF_lenkf_init + + SUBROUTINE c__PDAF_lenkf_alloc(outflag) bind(c) + use PDAF_lenkf + implicit none + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + + call PDAF_lenkf_alloc(outflag) + + END SUBROUTINE c__PDAF_lenkf_alloc + + SUBROUTINE c__PDAF_lenkf_config(subtype, verbose) bind(c) + use PDAF_lenkf + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAF_lenkf_config(subtype, verbose) + + END SUBROUTINE c__PDAF_lenkf_config + + SUBROUTINE c__PDAF_lenkf_set_iparam(id, value, flag) bind(c) + use PDAF_lenkf + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + INTEGER(c_int), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_lenkf_set_iparam(id, value, flag) + + END SUBROUTINE c__PDAF_lenkf_set_iparam + + SUBROUTINE c__PDAF_lenkf_set_rparam(id, value, flag) bind(c) + use PDAF_lenkf + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + REAL(c_double), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_lenkf_set_rparam(id, value, flag) + + END SUBROUTINE c__PDAF_lenkf_set_rparam + + SUBROUTINE c__PDAF_lenkf_options() bind(c) + use PDAF_lenkf + implicit none + call PDAF_lenkf_options() + + END SUBROUTINE c__PDAF_lenkf_options + + SUBROUTINE c__PDAF_lenkf_memtime(printtype) bind(c) + use PDAF_lenkf + implicit none + ! Type of screen output: + INTEGER(c_int), INTENT(in) :: printtype + + + call PDAF_lenkf_memtime(printtype) + + END SUBROUTINE c__PDAF_lenkf_memtime + + SUBROUTINE c__PDAF_lseik_init(subtype, param_int, dim_pint, param_real, & + dim_preal, ensemblefilter, fixedbasis, verbose, outflag) bind(c) + use PDAF_lseik + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Number of integer parameters + INTEGER(c_int), INTENT(in) :: dim_pint + ! Integer parameter array + INTEGER(c_int), DIMENSION(dim_pint), INTENT(inout) :: param_int + ! Number of real parameters + INTEGER(c_int), INTENT(in) :: dim_preal + ! Real parameter array + REAL(c_double), DIMENSION(dim_preal), INTENT(inout) :: param_real + ! Is the chosen filter ensemble-based? + LOGICAL(c_bool), INTENT(out) :: ensemblefilter + ! Does the filter run with fixed error-space basis? + LOGICAL(c_bool), INTENT(out) :: fixedbasis + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + logical :: ensemblefilter_out, fixedbasis_out + + call PDAF_lseik_init(subtype, param_int, dim_pint, param_real, dim_preal, & + ensemblefilter_out, fixedbasis_out, verbose, outflag) + ensemblefilter = ensemblefilter_out + fixedbasis = fixedbasis_out + END SUBROUTINE c__PDAF_lseik_init + + SUBROUTINE c__PDAF_lseik_alloc(outflag) bind(c) + use PDAF_lseik + implicit none + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + + call PDAF_lseik_alloc(outflag) + + END SUBROUTINE c__PDAF_lseik_alloc + + SUBROUTINE c__PDAF_lseik_config(subtype, verbose) bind(c) + use PDAF_lseik + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAF_lseik_config(subtype, verbose) + + END SUBROUTINE c__PDAF_lseik_config + + SUBROUTINE c__PDAF_lseik_set_iparam(id, value, flag) bind(c) + use PDAF_lseik + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + INTEGER(c_int), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_lseik_set_iparam(id, value, flag) + + END SUBROUTINE c__PDAF_lseik_set_iparam + + SUBROUTINE c__PDAF_lseik_set_rparam(id, value, flag) bind(c) + use PDAF_lseik + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + REAL(c_double), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_lseik_set_rparam(id, value, flag) + + END SUBROUTINE c__PDAF_lseik_set_rparam + + SUBROUTINE c__PDAF_lseik_options() bind(c) + use PDAF_lseik + implicit none + call PDAF_lseik_options() + + END SUBROUTINE c__PDAF_lseik_options + + SUBROUTINE c__PDAF_lseik_memtime(printtype) bind(c) + use PDAF_lseik + implicit none + ! Type of screen output: + INTEGER(c_int), INTENT(in) :: printtype + + + call PDAF_lseik_memtime(printtype) + + END SUBROUTINE c__PDAF_lseik_memtime + + + SUBROUTINE c__PDAF_etkf_init(subtype, param_int, dim_pint, param_real, & + dim_preal, ensemblefilter, fixedbasis, verbose, outflag) bind(c) + use PDAF_etkf + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Number of integer parameters + INTEGER(c_int), INTENT(in) :: dim_pint + ! Integer parameter array + INTEGER(c_int), DIMENSION(dim_pint), INTENT(inout) :: param_int + ! Number of real parameters + INTEGER(c_int), INTENT(in) :: dim_preal + ! Real parameter array + REAL(c_double), DIMENSION(dim_preal), INTENT(inout) :: param_real + ! Is the chosen filter ensemble-based? + LOGICAL(c_bool), INTENT(out) :: ensemblefilter + ! Does the filter run with fixed error-space basis? + LOGICAL(c_bool), INTENT(out) :: fixedbasis + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + logical :: ensemblefilter_out, fixedbasis_out + + call PDAF_etkf_init(subtype, param_int, dim_pint, param_real, dim_preal, & + ensemblefilter_out, fixedbasis_out, verbose, outflag) + ensemblefilter = ensemblefilter_out + fixedbasis = fixedbasis_out + END SUBROUTINE c__PDAF_etkf_init + + SUBROUTINE c__PDAF_etkf_alloc(outflag) bind(c) + use PDAF_etkf + implicit none + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + + call PDAF_etkf_alloc(outflag) + + END SUBROUTINE c__PDAF_etkf_alloc + + SUBROUTINE c__PDAF_etkf_config(subtype, verbose) bind(c) + use PDAF_etkf + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAF_etkf_config(subtype, verbose) + + END SUBROUTINE c__PDAF_etkf_config + + SUBROUTINE c__PDAF_etkf_set_iparam(id, value, flag) bind(c) + use PDAF_etkf + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + INTEGER(c_int), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_etkf_set_iparam(id, value, flag) + + END SUBROUTINE c__PDAF_etkf_set_iparam + + SUBROUTINE c__PDAF_etkf_set_rparam(id, value, flag) bind(c) + use PDAF_etkf + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + REAL(c_double), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_etkf_set_rparam(id, value, flag) + + END SUBROUTINE c__PDAF_etkf_set_rparam + + SUBROUTINE c__PDAF_etkf_options() bind(c) + use PDAF_etkf + implicit none + call PDAF_etkf_options() + + END SUBROUTINE c__PDAF_etkf_options + + SUBROUTINE c__PDAF_etkf_memtime(printtype) bind(c) + use PDAF_etkf + implicit none + ! Type of screen output: + INTEGER(c_int), INTENT(in) :: printtype + + + call PDAF_etkf_memtime(printtype) + + END SUBROUTINE c__PDAF_etkf_memtime + + SUBROUTINE c__PDAFlenkf_update(step, dim_p, dim_obs_p, dim_ens, state_p, & + ens_p, u_init_dim_obs, u_obs_op, u_add_obs_err, u_init_obs, & + u_init_obs_covar, u_prepoststep, u_localize, screen, subtype, flag) bind(c) + use PDAF_lenkf_update + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_p + ! Size of state ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Specification of filter subtype + INTEGER(c_int), INTENT(in) :: subtype + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Add observation error covariance matrix + procedure(c__add_obs_err_pdaf) :: u_add_obs_err + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Initialize observation error covariance matrix + procedure(c__init_obs_covar_pdaf) :: u_init_obs_covar + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Apply localization to HP and HPH^T + procedure(c__localize_covar_pdaf) :: u_localize + + call PDAFlenkf_update(step, dim_p, dim_obs_p, dim_ens, state_p, ens_p, & + u_init_dim_obs, u_obs_op, u_add_obs_err, u_init_obs, u_init_obs_covar, & + u_prepoststep, u_localize, screen, subtype, flag) + + END SUBROUTINE c__PDAFlenkf_update + + SUBROUTINE c__PDAF_PF_init(subtype, param_int, dim_pint, param_real, & + dim_preal, ensemblefilter, fixedbasis, verbose, outflag) bind(c) + use PDAF_PF + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Number of integer parameters + INTEGER(c_int), INTENT(in) :: dim_pint + ! Integer parameter array + INTEGER(c_int), DIMENSION(dim_pint), INTENT(inout) :: param_int + ! Number of real parameters + INTEGER(c_int), INTENT(in) :: dim_preal + ! Real parameter array + REAL(c_double), DIMENSION(dim_preal), INTENT(inout) :: param_real + ! Is the chosen filter ensemble-based? + LOGICAL(c_bool), INTENT(out) :: ensemblefilter + ! Does the filter run with fixed error-space basis? + LOGICAL(c_bool), INTENT(out) :: fixedbasis + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + logical :: ensemblefilter_out, fixedbasis_out + + call PDAF_PF_init(subtype, param_int, dim_pint, param_real, dim_preal, & + ensemblefilter_out, fixedbasis_out, verbose, outflag) + ensemblefilter = ensemblefilter_out + fixedbasis = fixedbasis_out + END SUBROUTINE c__PDAF_PF_init + + SUBROUTINE c__PDAF_pf_alloc(outflag) bind(c) + use PDAF_pf + implicit none + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + + call PDAF_pf_alloc(outflag) + + END SUBROUTINE c__PDAF_pf_alloc + + SUBROUTINE c__PDAF_pf_config(subtype, verbose) bind(c) + use PDAF_pf + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAF_pf_config(subtype, verbose) + + END SUBROUTINE c__PDAF_pf_config + + SUBROUTINE c__PDAF_pf_set_iparam(id, value, flag) bind(c) + use PDAF_pf + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + INTEGER(c_int), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_pf_set_iparam(id, value, flag) + + END SUBROUTINE c__PDAF_pf_set_iparam + + SUBROUTINE c__PDAF_pf_set_rparam(id, value, flag) bind(c) + use PDAF_pf + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + REAL(c_double), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_pf_set_rparam(id, value, flag) + + END SUBROUTINE c__PDAF_pf_set_rparam + + SUBROUTINE c__PDAF_pf_options() bind(c) + use PDAF_pf + implicit none + call PDAF_pf_options() + + END SUBROUTINE c__PDAF_pf_options + + SUBROUTINE c__PDAF_pf_memtime(printtype) bind(c) + use PDAF_pf + implicit none + ! Type of screen output: + INTEGER(c_int), INTENT(in) :: printtype + + + call PDAF_pf_memtime(printtype) + + END SUBROUTINE c__PDAF_pf_memtime + + SUBROUTINE c__PDAF_lknetf_ana_letkfT(domain_p, step, dim_l, dim_obs_l, & + dim_ens, state_l, ainv_l, ens_l, hz_l, hxbar_l, obs_l, rndmat, forget, & + u_prodrinva_hyb_l, u_init_obsvar_l, gamma, screen, type_forget, flag) bind(c) + use PDAF_lknetf_analysis_step + implicit none + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! State dimension on local analysis domain + INTEGER(c_int), INTENT(in) :: dim_l + ! Size of obs. vector on local ana. domain + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! local forecast state + REAL(c_double), DIMENSION(dim_l), INTENT(inout) :: state_l + ! local weight matrix for ensemble transformation + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(out) :: ainv_l + ! Local state ensemble + REAL(c_double), DIMENSION(dim_l, dim_ens), INTENT(inout) :: ens_l + ! PE-local full observed state ens. + REAL(c_double), DIMENSION(dim_obs_l, dim_ens), INTENT(inout) :: hz_l + ! local observed ens. mean + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: hxbar_l + ! Local observation vector + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: obs_l + ! Global random rotation matrix + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(inout) :: rndmat + ! Forgetting factor + REAL(c_double), INTENT(inout) :: forget + ! Hybrid weight for state transformation + REAL(c_double), DIMENSION(1), INTENT(inout) :: gamma + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Type of forgetting factor + INTEGER(c_int), INTENT(in) :: type_forget + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Provide product R^-1 A for local analysis domain including hybrid weight + procedure(c__prodrinva_hyb_l_pdaf) :: u_prodrinva_hyb_l + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + + prodrinva_hyb_l_pdaf_c_ptr => u_prodrinva_hyb_l + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + + call PDAF_lknetf_ana_letkfT(domain_p, step, dim_l, dim_obs_l, dim_ens, & + state_l, ainv_l, ens_l, hz_l, hxbar_l, obs_l, rndmat, forget, & + f__prodrinva_hyb_l_pdaf, f__init_obsvar_l_pdaf, gamma, screen, type_forget, flag) + + END SUBROUTINE c__PDAF_lknetf_ana_letkfT + + SUBROUTINE c__PDAF_lknetf_ana_lnetf(domain_p, step, dim_l, dim_obs_l, & + dim_ens, ens_l, hx_l, rndmat, obs_l, u_likelihood_hyb_l, cnt_small_svals, & + n_eff_all, gamma, screen, flag) bind(c) + use PDAF_lknetf_analysis_step + implicit none + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! State dimension on local analysis domain + INTEGER(c_int), INTENT(in) :: dim_l + ! Size of obs. vector on local ana. domain + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Local state ensemble + REAL(c_double), DIMENSION(dim_l, dim_ens), INTENT(inout) :: ens_l + ! local observed state ens. + REAL(c_double), DIMENSION(dim_obs_l, dim_ens), INTENT(in) :: hx_l + ! Global random rotation matrix + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(in) :: rndmat + ! Local observation vector + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: obs_l + ! Number of small eigen values + INTEGER(c_int), INTENT(inout) :: cnt_small_svals + ! Effective ensemble size + REAL(c_double), DIMENSION(1), INTENT(inout) :: n_eff_all + ! Hybrid weight for state transformation + REAL(c_double), DIMENSION(1), INTENT(inout) :: gamma + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Compute observation likelihood for an ensemble member with hybrid weight + procedure(c__likelihood_hyb_l_pdaf) :: u_likelihood_hyb_l + + likelihood_hyb_l_pdaf_c_ptr => u_likelihood_hyb_l + + call PDAF_lknetf_ana_lnetf(domain_p, step, dim_l, dim_obs_l, dim_ens, & + ens_l, hx_l, rndmat, obs_l, f__likelihood_hyb_l_pdaf, cnt_small_svals, & + n_eff_all, gamma, screen, flag) + + END SUBROUTINE c__PDAF_lknetf_ana_lnetf + + SUBROUTINE c__PDAF_enkf_ana_rsm(step, dim_p, dim_obs_p, dim_obs, dim_ens, rank_ana, & + state_p, ens_p, hx_p, hxbar_p, obs_p, u_add_obs_err, u_init_obs_covar, & + screen, debug, flag) bind(c) + use PDAF_enkf_analysis_rsm + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + !< Global dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs + ! Size of state ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Rank to be considered for inversion of HPH + INTEGER(c_int), INTENT(in) :: rank_ana + ! PE-local ensemble mean state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! PE-local observed ensemble + REAL(c_double), DIMENSION(dim_obs_p, dim_ens), INTENT(in) :: hx_p + ! PE-local observed state + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: hxbar_p + ! PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Add observation error covariance matrix + procedure(c__add_obs_err_pdaf) :: u_add_obs_err + ! Initialize observation error covariance matrix + procedure(c__init_obs_covar_pdaf) :: u_init_obs_covar + + add_obs_err_pdaf_c_ptr => u_add_obs_err + init_obs_covar_pdaf_c_ptr => u_init_obs_covar + + call PDAF_enkf_ana_rsm(step, dim_p, dim_obs_p, dim_obs, dim_ens, rank_ana, & + state_p, ens_p, hx_p, hxbar_p, obs_p, f__add_obs_err_pdaf, f__init_obs_covar_pdaf, & + screen, debug, flag) + + END SUBROUTINE c__PDAF_enkf_ana_rsm + + SUBROUTINE c__PDAF_lknetf_init(subtype, param_int, dim_pint, param_real, & + dim_preal, ensemblefilter, fixedbasis, verbose, outflag) bind(c) + use PDAF_lknetf + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Number of integer parameters + INTEGER(c_int), INTENT(in) :: dim_pint + ! Integer parameter array + INTEGER(c_int), DIMENSION(dim_pint), INTENT(inout) :: param_int + ! Number of real parameters + INTEGER(c_int), INTENT(in) :: dim_preal + ! Real parameter array + REAL(c_double), DIMENSION(dim_preal), INTENT(inout) :: param_real + ! Is the chosen filter ensemble-based? + LOGICAL(c_bool), INTENT(out) :: ensemblefilter + ! Does the filter run with fixed error-space basis? + LOGICAL(c_bool), INTENT(out) :: fixedbasis + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + logical :: ensemblefilter_out, fixedbasis_out + + call PDAF_lknetf_init(subtype, param_int, dim_pint, param_real, & + dim_preal, ensemblefilter_out, fixedbasis_out, verbose, outflag) + ensemblefilter = ensemblefilter_out + fixedbasis = fixedbasis_out + END SUBROUTINE c__PDAF_lknetf_init + + SUBROUTINE c__PDAF_lknetf_alloc(outflag) bind(c) + use PDAF_lknetf + implicit none + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + + call PDAF_lknetf_alloc(outflag) + + END SUBROUTINE c__PDAF_lknetf_alloc + + SUBROUTINE c__PDAF_lknetf_config(subtype, verbose) bind(c) + use PDAF_lknetf + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAF_lknetf_config(subtype, verbose) + + END SUBROUTINE c__PDAF_lknetf_config + + SUBROUTINE c__PDAF_lknetf_set_iparam(id, value, flag) bind(c) + use PDAF_lknetf + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + INTEGER(c_int), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_lknetf_set_iparam(id, value, flag) + + END SUBROUTINE c__PDAF_lknetf_set_iparam + + SUBROUTINE c__PDAF_lknetf_set_rparam(id, value, flag) bind(c) + use PDAF_lknetf + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + REAL(c_double), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_lknetf_set_rparam(id, value, flag) + + END SUBROUTINE c__PDAF_lknetf_set_rparam + + SUBROUTINE c__PDAF_lknetf_options() bind(c) + use PDAF_lknetf + implicit none + call PDAF_lknetf_options() + + END SUBROUTINE c__PDAF_lknetf_options + + SUBROUTINE c__PDAF_lknetf_memtime(printtype) bind(c) + use PDAF_lknetf + implicit none + ! Type of screen output: + INTEGER(c_int), INTENT(in) :: printtype + + + call PDAF_lknetf_memtime(printtype) + + END SUBROUTINE c__PDAF_lknetf_memtime + + SUBROUTINE c__PDAF_lknetf_alpha_neff(dim_ens, weights, hlimit, alpha) bind(c) + use PDAF_lknetf + implicit none + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Weights + REAL(c_double), DIMENSION(dim_ens), INTENT(in) :: weights + ! Minimum of n_eff / N + REAL(c_double), INTENT(in) :: hlimit + ! hybrid weight + REAL(c_double), INTENT(inout) :: alpha + + + call PDAF_lknetf_alpha_neff(dim_ens, weights, hlimit, alpha) + + END SUBROUTINE c__PDAF_lknetf_alpha_neff + + SUBROUTINE c__PDAF_lknetf_compute_gamma(domain_p, step, dim_obs_l, dim_ens, & + hx_l, hxbar_l, obs_l, type_hyb, hyb_g, hyb_k, gamma, n_eff_out, & + skew_mabs, kurt_mabs, u_likelihood_l, screen, flag) bind(c) + use PDAF_lknetf, only: PDAF_lknetf_compute_gamma + implicit none + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Size of obs. vector on local ana. domain + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! local observed state ens. + REAL(c_double), DIMENSION(dim_obs_l, dim_ens), INTENT(in) :: hx_l + ! local mean observed ensemble + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: hxbar_l + ! Local observation vector + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: obs_l + ! Type of hybrid weight + INTEGER(c_int), INTENT(in) :: type_hyb + ! Prescribed hybrid weight for state transformation + REAL(c_double), INTENT(in) :: hyb_g + ! Hybrid weight for covariance transformation + REAL(c_double), INTENT(in) :: hyb_k + ! Hybrid weight for state transformation + REAL(c_double), DIMENSION(1), INTENT(inout) :: gamma + ! Effective ensemble size + REAL(c_double), DIMENSION(1), INTENT(inout) :: n_eff_out + ! Mean absolute skewness + REAL(c_double), DIMENSION(1), INTENT(inout) :: skew_mabs + ! Mean absolute kurtosis + REAL(c_double), DIMENSION(1), INTENT(inout) :: kurt_mabs + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Compute observation likelihood for an ensemble member + procedure(c__likelihood_l_pdaf) :: u_likelihood_l + + likelihood_l_pdaf_c_ptr => u_likelihood_l + + call PDAF_lknetf_compute_gamma(domain_p, step, dim_obs_l, dim_ens, hx_l, & + hxbar_l, obs_l, type_hyb, hyb_g, hyb_k, gamma, n_eff_out, skew_mabs, & + kurt_mabs, f__likelihood_l_pdaf, screen, flag) + + END SUBROUTINE c__PDAF_lknetf_compute_gamma + + SUBROUTINE c__PDAF_lknetf_set_gamma(domain_p, dim_obs_l, dim_ens, hx_l, & + hxbar_l, weights, type_hyb, hyb_g, hyb_k, gamma, n_eff_out, maskew, & + makurt, screen, flag) bind(c) + use PDAF_lknetf, only: PDAF_lknetf_set_gamma + implicit none + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Size of obs. vector on local ana. domain + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! local observed state ens. + REAL(c_double), DIMENSION(dim_obs_l, dim_ens), INTENT(in) :: hx_l + ! local mean observed ensemble + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: hxbar_l + ! Weight vector + REAL(c_double), DIMENSION(dim_ens), INTENT(in) :: weights + ! Type of hybrid weight + INTEGER(c_int), INTENT(in) :: type_hyb + ! Prescribed hybrid weight for state transformation + REAL(c_double), INTENT(in) :: hyb_g + ! Scale factor kappa (for type_hyb 3 and 4) + REAL(c_double), INTENT(in) :: hyb_k + ! Hybrid weight for state transformation + REAL(c_double), DIMENSION(1), INTENT(inout) :: gamma + ! Effective ensemble size + REAL(c_double), DIMENSION(1), INTENT(inout) :: n_eff_out + ! Mean absolute skewness + REAL(c_double), DIMENSION(1), INTENT(inout) :: maskew + ! Mean absolute kurtosis + REAL(c_double), DIMENSION(1), INTENT(inout) :: makurt + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + + call PDAF_lknetf_set_gamma(domain_p, dim_obs_l, dim_ens, hx_l, hxbar_l, & + weights, type_hyb, hyb_g, hyb_k, gamma, n_eff_out, maskew, makurt, & + screen, flag) + + END SUBROUTINE c__PDAF_lknetf_set_gamma + + SUBROUTINE c__PDAF_lknetf_reset_gamma(gamma_in) bind(c) + use PDAF_lknetf + implicit none + ! Prescribed hybrid weight + REAL(c_double), INTENT(in) :: gamma_in + + + call PDAF_lknetf_reset_gamma(gamma_in) + + END SUBROUTINE c__PDAF_lknetf_reset_gamma + + SUBROUTINE c__PDAFhyb3dvar_analysis_cvt(step, dim_p, dim_obs_p, dim_ens, & + dim_cvec, dim_cvec_ens, beta_3dvar, state_p, ens_p, state_inc_p, hxbar_p, & + obs_p, u_prodrinva, u_cvt, u_cvt_adj, u_cvt_ens, u_cvt_adj_ens, & + u_obs_op_lin, u_obs_op_adj, screen, type_opt, debug, flag) bind(c) + use PDAF_hyb3dvar_analysis_cvt + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Size of control vector (parameterized part) + INTEGER(c_int), INTENT(in) :: dim_cvec + ! Size of control vector (ensemble part) + INTEGER(c_int), INTENT(in) :: dim_cvec_ens + ! Hybrid weight for hybrid 3D-Var + REAL(c_double), INTENT(in) :: beta_3dvar + ! on exit: PE-local forecast state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! PE-local state analysis increment + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_inc_p + ! PE-local observed state + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: hxbar_p + ! PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Type of minimizer for 3DVar + INTEGER(c_int), INTENT(in) :: type_opt + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector (parameterized) + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix (parameterized) + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Apply control vector transform matrix to control vector (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + + call PDAFhyb3dvar_analysis_cvt(step, dim_p, dim_obs_p, dim_ens, dim_cvec, & + dim_cvec_ens, beta_3dvar, state_p, ens_p, state_inc_p, hxbar_p, obs_p, & + u_prodrinva, u_cvt, u_cvt_adj, u_cvt_ens, u_cvt_adj_ens, u_obs_op_lin, & + u_obs_op_adj, screen, type_opt, debug, flag) + + END SUBROUTINE c__PDAFhyb3dvar_analysis_cvt + + SUBROUTINE c__PDAF3dvar_analysis_cvt(step, dim_p, dim_obs_p, dim_cvec, & + state_p, hxbar_p, obs_p, u_prodrinva, u_cvt, u_cvt_adj, u_obs_op_lin, & + u_obs_op_adj, screen, type_opt, debug, flag) bind(c) + use PDAF_3dvar_analysis_cvt + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Size of control vector + INTEGER(c_int), INTENT(in) :: dim_cvec + ! on exit: PE-local forecast state + REAL(c_double), DIMENSION(dim_p), INTENT(out) :: state_p + ! PE-local observed state + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: hxbar_p + ! PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Type of minimizer for 3DVar + INTEGER(c_int), INTENT(in) :: type_opt + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + + call PDAF3dvar_analysis_cvt(step, dim_p, dim_obs_p, dim_cvec, state_p, & + hxbar_p, obs_p, u_prodrinva, u_cvt, u_cvt_adj, u_obs_op_lin, & + u_obs_op_adj, screen, type_opt, debug, flag) + + END SUBROUTINE c__PDAF3dvar_analysis_cvt + + SUBROUTINE c__PDAF_lestkf_init(subtype, param_int, dim_pint, param_real, & + dim_preal, ensemblefilter, fixedbasis, verbose, outflag) bind(c) + use PDAF_lestkf + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Number of integer parameters + INTEGER(c_int), INTENT(in) :: dim_pint + ! Integer parameter array + INTEGER(c_int), DIMENSION(dim_pint), INTENT(inout) :: param_int + ! Number of real parameters + INTEGER(c_int), INTENT(in) :: dim_preal + ! Real parameter array + REAL(c_double), DIMENSION(dim_preal), INTENT(inout) :: param_real + ! Is the chosen filter ensemble-based? + LOGICAL(c_bool), INTENT(out) :: ensemblefilter + ! Does the filter run with fixed error-space basis? + LOGICAL(c_bool), INTENT(out) :: fixedbasis + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + logical :: ensemblefilter_out, fixedbasis_out + + + call PDAF_lestkf_init(subtype, param_int, dim_pint, param_real, & + dim_preal, ensemblefilter_out, fixedbasis_out, verbose, outflag) + ensemblefilter = ensemblefilter_out + fixedbasis = fixedbasis_out + + END SUBROUTINE c__PDAF_lestkf_init + + SUBROUTINE c__PDAF_lestkf_alloc(outflag) bind(c) + use PDAF_lestkf + implicit none + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + + call PDAF_lestkf_alloc(outflag) + + END SUBROUTINE c__PDAF_lestkf_alloc + + SUBROUTINE c__PDAF_lestkf_config(subtype, verbose) bind(c) + use PDAF_lestkf + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAF_lestkf_config(subtype, verbose) + + END SUBROUTINE c__PDAF_lestkf_config + + SUBROUTINE c__PDAF_lestkf_set_iparam(id, value, flag) bind(c) + use PDAF_lestkf + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + INTEGER(c_int), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_lestkf_set_iparam(id, value, flag) + + END SUBROUTINE c__PDAF_lestkf_set_iparam + + SUBROUTINE c__PDAF_lestkf_set_rparam(id, value, flag) bind(c) + use PDAF_lestkf + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + REAL(c_double), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_lestkf_set_rparam(id, value, flag) + + END SUBROUTINE c__PDAF_lestkf_set_rparam + + SUBROUTINE c__PDAF_lestkf_options() bind(c) + use PDAF_lestkf + implicit none + call PDAF_lestkf_options() + + END SUBROUTINE c__PDAF_lestkf_options + + SUBROUTINE c__PDAF_lestkf_memtime(printtype) bind(c) + use PDAF_lestkf + implicit none + ! Type of screen output: + INTEGER(c_int), INTENT(in) :: printtype + + + call PDAF_lestkf_memtime(printtype) + + END SUBROUTINE c__PDAF_lestkf_memtime + + SUBROUTINE c__PDAF_seik_ana(step, dim_p, dim_obs_p, dim_ens, rank, state_p, & + uinv, ens_p, hl_p, hxbar_p, obs_p, forget, u_prodrinva, debug, flag) bind(c) + use PDAF_seik_analysis + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: rank + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Inverse of eigenvalue matrix U + REAL(c_double), DIMENSION(rank, rank), INTENT(inout) :: uinv + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! PE-local observed ensemble (perturbations) + REAL(c_double), DIMENSION(dim_obs_p, dim_ens), INTENT(inout) :: hl_p + ! PE-local observed state + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: hxbar_p + ! PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Forgetting factor + REAL(c_double), INTENT(in) :: forget + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + + prodrinva_pdaf_c_ptr => u_prodrinva + + call PDAF_seik_ana(step, dim_p, dim_obs_p, dim_ens, rank, state_p, uinv, & + ens_p, hl_p, hxbar_p, obs_p, forget, f__prodrinva_pdaf, debug, flag) + + END SUBROUTINE c__PDAF_seik_ana + + SUBROUTINE c__PDAF_seik_resample(subtype, dim_p, dim_ens, rank, uinv, & + state_p, enst_p, type_sqrt, type_trans, nm1vsn, screen, flag) bind(c) + use PDAF_seik_analysis + implicit none + ! Filter subtype + INTEGER(c_int), INTENT(in) :: subtype + ! PE-local state dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: rank + ! Inverse of matrix U + REAL(c_double), DIMENSION(rank, rank), INTENT(inout) :: uinv + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! PE-local ensemble times T + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: enst_p + ! Type of square-root of A + INTEGER(c_int), INTENT(in) :: type_sqrt + ! Type of ensemble transformation + INTEGER(c_int), INTENT(in) :: type_trans + ! Flag which normalization of P ist used in SEIK + INTEGER(c_int), INTENT(in) :: nm1vsn + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + + call PDAF_seik_resample(subtype, dim_p, dim_ens, rank, uinv, state_p, & + enst_p, type_sqrt, type_trans, nm1vsn, screen, flag) + + END SUBROUTINE c__PDAF_seik_resample + + SUBROUTINE c__PDAF_lseik_ana(domain_p, step, dim_l, dim_obs_l, dim_ens, & + rank, state_l, uinv_l, ens_l, hl_l, hxbar_l, obs_l, forget, & + u_prodrinva_l, screen, debug, flag) bind(c) + use PDAF_lseik_analysis + implicit none + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! State dimension on local analysis domain + INTEGER(c_int), INTENT(in) :: dim_l + ! Size of obs. vector on local ana. domain + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: rank + ! State on local analysis domain + REAL(c_double), DIMENSION(dim_l), INTENT(inout) :: state_l + ! Inverse of matrix U + REAL(c_double), DIMENSION(rank, rank), INTENT(inout) :: uinv_l + ! Local state ensemble + REAL(c_double), DIMENSION(dim_l, dim_ens), INTENT(in) :: ens_l + ! Local observed state ensemble (perturbation) + REAL(c_double), DIMENSION(dim_obs_l, dim_ens), INTENT(inout) :: hl_l + ! Local observed ensemble mean + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: hxbar_l + ! Local observation vector + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: obs_l + ! Forgetting factor + REAL(c_double), INTENT(inout) :: forget + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Provide product R^-1 A for local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + + call PDAF_lseik_ana(domain_p, step, dim_l, dim_obs_l, dim_ens, rank, & + state_l, uinv_l, ens_l, hl_l, hxbar_l, obs_l, forget, f__prodrinva_l_pdaf, & + screen, debug, flag) + + END SUBROUTINE c__PDAF_lseik_ana + + SUBROUTINE c__PDAF_lseik_resample(domain_p, subtype, dim_l, dim_ens, rank, & + uinv_l, state_l, ens_l, omegat_in, type_sqrt, screen, flag) bind(c) + use PDAF_lseik_analysis + implicit none + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Specification of filter subtype + INTEGER(c_int), INTENT(in) :: subtype + ! State dimension on local analysis domain + INTEGER(c_int), INTENT(in) :: dim_l + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: rank + ! Inverse of matrix U + REAL(c_double), DIMENSION(rank, rank), INTENT(inout) :: uinv_l + ! Local model state + REAL(c_double), DIMENSION(dim_l), INTENT(inout) :: state_l + ! Local state ensemble + REAL(c_double), DIMENSION(dim_l, dim_ens), INTENT(inout) :: ens_l + ! Matrix Omega + REAL(c_double), DIMENSION(rank, dim_ens), INTENT(inout) :: omegat_in + ! Type of square-root of A + INTEGER(c_int), INTENT(in) :: type_sqrt + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + + call PDAF_lseik_resample(domain_p, subtype, dim_l, dim_ens, rank, uinv_l, & + state_l, ens_l, omegat_in, type_sqrt, screen, flag) + + END SUBROUTINE c__PDAF_lseik_resample + + SUBROUTINE c__PDAF_prepost(u_collect_state, u_distribute_state, & + u_prepoststep, u_next_observation, outflag) bind(c) + use PDAFprepost + implicit none + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + prepoststep_pdaf_c_ptr => u_prepoststep + next_observation_pdaf_c_ptr => u_next_observation + + call PDAF_prepost(f__collect_state_pdaf, f__distribute_state_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAF_prepost + + SUBROUTINE c__PDAFenkf_update(step, dim_p, dim_obs_p, dim_ens, state_p, & + ens_p, u_init_dim_obs, u_obs_op, u_add_obs_err, u_init_obs, & + u_init_obs_covar, u_prepoststep, screen, subtype, dim_lag, sens_p, & + cnt_maxlag, flag) bind(c) + use PDAF_enkf_update + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_p + ! Size of state ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Specification of filter subtype + INTEGER(c_int), INTENT(in) :: subtype + ! Number of past time instances for smoother + INTEGER(c_int), INTENT(in) :: dim_lag + ! PE-local smoother ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens, dim_lag), INTENT(inout) :: sens_p + ! Count number of past time steps for smoothing + INTEGER(c_int), INTENT(inout) :: cnt_maxlag + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Add observation error covariance matrix + procedure(c__add_obs_err_pdaf) :: u_add_obs_err + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Initialize observation error covariance matrix + procedure(c__init_obs_covar_pdaf) :: u_init_obs_covar + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + call PDAFenkf_update(step, dim_p, dim_obs_p, dim_ens, state_p, ens_p, & + u_init_dim_obs, u_obs_op, u_add_obs_err, u_init_obs, u_init_obs_covar, & + u_prepoststep, screen, subtype, dim_lag, sens_p, cnt_maxlag, flag) + + END SUBROUTINE c__PDAFenkf_update + + SUBROUTINE c__PDAF_init_parallel(dim_ens, ensemblefilter, fixedbasis, & + in_comm_model, in_comm_filter, in_comm_couple, in_n_modeltasks, in_task_id, & + screen, flag) bind(c) + use PDAF_mod_parallel + implicit none + ! Rank of covar matrix/ensemble size + INTEGER(c_int), INTENT(inout) :: dim_ens + ! Is the filter ensemble-based? + LOGICAL(c_bool), INTENT(in) :: ensemblefilter + ! Run with fixed error-space basis? + LOGICAL(c_bool), INTENT(in) :: fixedbasis + ! Model communicator (not shared) + INTEGER(c_int), INTENT(in) :: in_comm_model + ! Filter communicator + INTEGER(c_int), INTENT(in) :: in_comm_filter + ! Coupling communicator + INTEGER(c_int), INTENT(in) :: in_comm_couple + ! Number of model tasks + INTEGER(c_int), INTENT(in) :: in_n_modeltasks + ! Task ID of current PE + INTEGER(c_int), INTENT(in) :: in_task_id + ! Whether screen information is shown + INTEGER(c_int), INTENT(in) :: screen + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + call PDAF_init_parallel(dim_ens, logical(ensemblefilter), logical(fixedbasis), in_comm_model, & + in_comm_filter, in_comm_couple, in_n_modeltasks, in_task_id, screen, flag) + + END SUBROUTINE c__PDAF_init_parallel + + SUBROUTINE c__PDAF_seik_init(subtype, param_int, dim_pint, param_real, & + dim_preal, ensemblefilter, fixedbasis, verbose, outflag) bind(c) + use PDAF_seik + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(in) :: subtype + ! Number of integer parameters + INTEGER(c_int), INTENT(in) :: dim_pint + ! Integer parameter array + INTEGER(c_int), DIMENSION(dim_pint), INTENT(inout) :: param_int + ! Number of real parameters + INTEGER(c_int), INTENT(in) :: dim_preal + ! Real parameter array + REAL(c_double), DIMENSION(dim_preal), INTENT(inout) :: param_real + ! Is the chosen filter ensemble-based? + LOGICAL(c_bool), INTENT(out) :: ensemblefilter + ! Does the filter run with fixed error-space basis? + LOGICAL(c_bool), INTENT(out) :: fixedbasis + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + logical :: ensemblefilter_out, fixedbasis_out + + call PDAF_seik_init(subtype, param_int, dim_pint, param_real, dim_preal, & + ensemblefilter_out, fixedbasis_out, verbose, outflag) + ensemblefilter = ensemblefilter_out + fixedbasis = fixedbasis_out + END SUBROUTINE c__PDAF_seik_init + + SUBROUTINE c__PDAF_seik_alloc(outflag) bind(c) + use PDAF_seik + implicit none + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + + call PDAF_seik_alloc(outflag) + + END SUBROUTINE c__PDAF_seik_alloc + + SUBROUTINE c__PDAF_seik_config(subtype, verbose) bind(c) + use PDAF_seik + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAF_seik_config(subtype, verbose) + + END SUBROUTINE c__PDAF_seik_config + + SUBROUTINE c__PDAF_seik_set_iparam(id, value, flag) bind(c) + use PDAF_seik + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + INTEGER(c_int), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_seik_set_iparam(id, value, flag) + + END SUBROUTINE c__PDAF_seik_set_iparam + + SUBROUTINE c__PDAF_seik_set_rparam(id, value, flag) bind(c) + use PDAF_seik + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + REAL(c_double), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_seik_set_rparam(id, value, flag) + + END SUBROUTINE c__PDAF_seik_set_rparam + + SUBROUTINE c__PDAF_seik_options() bind(c) + use PDAF_seik + implicit none + call PDAF_seik_options() + + END SUBROUTINE c__PDAF_seik_options + + SUBROUTINE c__PDAF_seik_memtime(printtype) bind(c) + use PDAF_seik + implicit none + ! Type of screen output: + INTEGER(c_int), INTENT(in) :: printtype + + + call PDAF_seik_memtime(printtype) + + END SUBROUTINE c__PDAF_seik_memtime + + SUBROUTINE c__PDAFnetf_update(step, dim_p, dim_obs_p, dim_ens, state_p, & + ainv, ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_likelihood, & + u_prepoststep, screen, subtype, dim_lag, sens_p, cnt_maxlag, flag) bind(c) + use PDAF_netf_update + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Inverse of matrix U + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(inout) :: ainv + ! PE-local ensemble matrix + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Filter subtype + INTEGER(c_int), INTENT(in) :: subtype + ! Number of past time instances for smoother + INTEGER(c_int), INTENT(in) :: dim_lag + ! PE-local smoother ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens, dim_lag), INTENT(inout) :: sens_p + ! Count number of past time steps for smoothing + INTEGER(c_int), INTENT(inout) :: cnt_maxlag + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Compute observation likelihood for an ensemble member + procedure(c__likelihood_pdaf) :: u_likelihood + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + call PDAFnetf_update(step, dim_p, dim_obs_p, dim_ens, state_p, ainv, & + ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_likelihood, & + u_prepoststep, screen, subtype, dim_lag, sens_p, cnt_maxlag, flag) + + END SUBROUTINE c__PDAFnetf_update + + SUBROUTINE c__PDAF_seik_ana_newT(step, dim_p, dim_obs_p, dim_ens, rank, & + state_p, uinv, ens_p, hl_p, hxbar_p, obs_p, forget, u_prodrinva, screen, & + debug, flag) bind(c) + use PDAF_seik_analysis_newT + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: rank + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Inverse of eigenvalue matrix U + REAL(c_double), DIMENSION(rank, rank), INTENT(inout) :: uinv + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! PE-local observed ensemble (perturbations) + REAL(c_double), DIMENSION(dim_obs_p, dim_ens), INTENT(inout) :: hl_p + ! PE-local observed state + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: hxbar_p + ! PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Forgetting factor + REAL(c_double), INTENT(in) :: forget + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + + prodrinva_pdaf_c_ptr => u_prodrinva + + call PDAF_seik_ana_newT(step, dim_p, dim_obs_p, dim_ens, rank, state_p, & + uinv, ens_p, hl_p, hxbar_p, obs_p, forget, f__prodrinva_pdaf, screen, debug, & + flag) + + END SUBROUTINE c__PDAF_seik_ana_newT + + SUBROUTINE c__PDAF_seik_resample_newT(subtype, dim_p, dim_ens, rank, uinv, & + state_p, ens_p, type_sqrt, type_trans, nm1vsn, screen, flag) bind(c) + use PDAF_seik_analysis_newT + implicit none + ! Filter subtype + INTEGER(c_int), INTENT(in) :: subtype + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: rank + ! Inverse of matrix U + REAL(c_double), DIMENSION(rank, rank), INTENT(inout) :: uinv + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Type of square-root of A + INTEGER(c_int), INTENT(in) :: type_sqrt + ! Type of ensemble transformation + INTEGER(c_int), INTENT(in) :: type_trans + ! Flag which normalization of P ist used in SEIK + INTEGER(c_int), INTENT(in) :: nm1vsn + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + + call PDAF_seik_resample_newT(subtype, dim_p, dim_ens, rank, uinv, & + state_p, ens_p, type_sqrt, type_trans, nm1vsn, screen, flag) + + END SUBROUTINE c__PDAF_seik_resample_newT + + SUBROUTINE c__PDAF_lenkf_ana_rsm(step, dim_p, dim_obs_p, dim_obs, dim_ens, rank_ana, & + state_p, ens_p, hx_p, hxbar_p, obs_p, u_add_obs_err, u_init_obs_covar, & + u_localize, screen, debug, flag) bind(c) + use PDAF_lenkf_analysis_rsm + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + !< Global dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs + ! Size of state ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Rank to be considered for inversion of HPH + INTEGER(c_int), INTENT(in) :: rank_ana + ! PE-local ensemble mean state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! PE-local observed ensemble + REAL(c_double), DIMENSION(dim_obs_p, dim_ens), INTENT(in) :: hx_p + ! PE-local observed state + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: hxbar_p + ! PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Add observation error covariance matrix + procedure(c__add_obs_err_pdaf) :: u_add_obs_err + ! Initialize observation error covariance matrix + procedure(c__init_obs_covar_pdaf) :: u_init_obs_covar + ! Apply localization to HP and HPH^T + procedure(c__localize_covar_pdaf) :: u_localize + + add_obs_err_pdaf_c_ptr => u_add_obs_err + init_obs_covar_pdaf_c_ptr => u_init_obs_covar + localize_covar_pdaf_c_ptr => u_localize + + call PDAF_lenkf_ana_rsm(step, dim_p, dim_obs_p, dim_obs, dim_ens, rank_ana, & + state_p, ens_p, hx_p, hxbar_p, obs_p, f__add_obs_err_pdaf, f__init_obs_covar_pdaf, & + f__localize_covar_pdaf, screen, debug, flag) + + END SUBROUTINE c__PDAF_lenkf_ana_rsm + + SUBROUTINE c__PDAF_lestkf_ana(domain_p, step, dim_l, dim_obs_l, dim_ens, & + rank, state_l, ainv_l, ens_l, hl_l, hxbar_l, obs_l, omegat_in, forget, & + u_prodrinva_l, envar_mode, type_sqrt, ta, screen, debug, flag) bind(c) + use PDAF_lestkf_analysis + implicit none + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! State dimension on local analysis domain + INTEGER(c_int), INTENT(in) :: dim_l + ! Size of obs. vector on local ana. domain + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: rank + ! state on local analysis domain + REAL(c_double), DIMENSION(dim_l), INTENT(inout) :: state_l + ! Inverse of matrix U - temporary use only + REAL(c_double), DIMENSION(rank, rank), INTENT(inout) :: ainv_l + ! Local state ensemble + REAL(c_double), DIMENSION(dim_l, dim_ens), INTENT(inout) :: ens_l + ! Local observed state ensemble (perturbation) + REAL(c_double), DIMENSION(dim_obs_l, dim_ens), INTENT(inout) :: hl_l + ! Local observed ensemble mean + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: hxbar_l + ! Local observation vector + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: obs_l + ! Matrix Omega + REAL(c_double), DIMENSION(rank, dim_ens), INTENT(in) :: omegat_in + ! Forgetting factor + REAL(c_double), INTENT(inout) :: forget + ! Flag whether routine is called from 3DVar for special functionality + INTEGER(c_int), INTENT(in) :: envar_mode + ! Type of square-root of A + INTEGER(c_int), INTENT(in) :: type_sqrt + ! Ensemble transformation matrix + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(inout) :: ta + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Provide product R^-1 A for local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + + call PDAF_lestkf_ana(domain_p, step, dim_l, dim_obs_l, dim_ens, rank, & + state_l, ainv_l, ens_l, hl_l, hxbar_l, obs_l, omegat_in, forget, & + f__prodrinva_l_pdaf, envar_mode, type_sqrt, ta, screen, debug, flag) + + END SUBROUTINE c__PDAF_lestkf_ana + + SUBROUTINE c__PDAFlestkf_update(step, dim_p, dim_obs_f, dim_ens, rank, & + state_p, ainv, ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_init_obs_l, & + u_prodrinva_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + u_prepoststep, screen, subtype, envar_mode, dim_lag, sens_p, cnt_maxlag, & + flag) bind(c) + use PDAF_lestkf_update + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_f + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: rank + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Inverse of matrix U + REAL(c_double), DIMENSION(rank, rank), INTENT(inout) :: ainv + ! PE-local ensemble matrix + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Filter subtype + INTEGER(c_int), INTENT(in) :: subtype + ! Flag whether routine is called from 3DVar for special functionality + INTEGER(c_int), INTENT(in) :: envar_mode + ! Number of past time instances for smoother + INTEGER(c_int), INTENT(in) :: dim_lag + ! PE-local smoother ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens, dim_lag), INTENT(inout) :: sens_p + ! Count number of past time steps for smoothing + INTEGER(c_int), INTENT(inout) :: cnt_maxlag + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! Compute product of R^(-1) with HV + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from global state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + call PDAFlestkf_update(step, dim_p, dim_obs_f, dim_ens, rank, state_p, & + ainv, ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_init_obs_l, & + u_prodrinva_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + u_prepoststep, screen, subtype, envar_mode, dim_lag, sens_p, & + cnt_maxlag, flag) + + END SUBROUTINE c__PDAFlestkf_update + + SUBROUTINE c__PDAF_LNETF_init(subtype, param_int, dim_pint, param_real, & + dim_preal, ensemblefilter, fixedbasis, verbose, outflag) bind(c) + use PDAF_LNETF + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Number of integer parameters + INTEGER(c_int), INTENT(in) :: dim_pint + ! Integer parameter array + INTEGER(c_int), DIMENSION(dim_pint), INTENT(inout) :: param_int + ! Number of real parameters + INTEGER(c_int), INTENT(in) :: dim_preal + ! Real parameter array + REAL(c_double), DIMENSION(dim_preal), INTENT(inout) :: param_real + ! Is the chosen filter ensemble-based? + LOGICAL(c_bool), INTENT(out) :: ensemblefilter + ! Does the filter run with fixed error-space basis? + LOGICAL(c_bool), INTENT(out) :: fixedbasis + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + logical :: ensemblefilter_out, fixedbasis_out + + call PDAF_LNETF_init(subtype, param_int, dim_pint, param_real, dim_preal, & + ensemblefilter_out, fixedbasis_out, verbose, outflag) + ensemblefilter = ensemblefilter_out + fixedbasis = fixedbasis_out + END SUBROUTINE c__PDAF_LNETF_init + + SUBROUTINE c__PDAF_lnetf_alloc(outflag) bind(c) + use PDAF_LNETF + implicit none + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + + call PDAF_lnetf_alloc(outflag) + + END SUBROUTINE c__PDAF_lnetf_alloc + + SUBROUTINE c__PDAF_lnetf_config(subtype, verbose) bind(c) + use PDAF_LNETF + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAF_lnetf_config(subtype, verbose) + + END SUBROUTINE c__PDAF_lnetf_config + + SUBROUTINE c__PDAF_lnetf_set_iparam(id, value, flag) bind(c) + use PDAF_LNETF + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + INTEGER(c_int), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_lnetf_set_iparam(id, value, flag) + + END SUBROUTINE c__PDAF_lnetf_set_iparam + + SUBROUTINE c__PDAF_lnetf_set_rparam(id, value, flag) bind(c) + use PDAF_LNETF + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + REAL(c_double), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_lnetf_set_rparam(id, value, flag) + + END SUBROUTINE c__PDAF_lnetf_set_rparam + + SUBROUTINE c__PDAF_lnetf_options() bind(c) + use PDAF_LNETF + implicit none + call PDAF_lnetf_options() + + END SUBROUTINE c__PDAF_lnetf_options + + SUBROUTINE c__PDAF_lnetf_memtime(printtype) bind(c) + use PDAF_LNETF + implicit none + ! Type of screen output: + INTEGER(c_int), INTENT(in) :: printtype + + + call PDAF_lnetf_memtime(printtype) + + END SUBROUTINE c__PDAF_lnetf_memtime + + SUBROUTINE c__PDAF_enkf_init(subtype, param_int, dim_pint, param_real, & + dim_preal, ensemblefilter, fixedbasis, verbose, outflag) bind(c) + use PDAF_enkf + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Number of integer parameters + INTEGER(c_int), INTENT(in) :: dim_pint + ! Integer parameter array + INTEGER(c_int), DIMENSION(dim_pint), INTENT(inout) :: param_int + ! Number of real parameters + INTEGER(c_int), INTENT(in) :: dim_preal + ! Real parameter array + REAL(c_double), DIMENSION(dim_preal), INTENT(inout) :: param_real + ! Is the chosen filter ensemble-based? + LOGICAL(c_bool), INTENT(out) :: ensemblefilter + ! Does the filter run with fixed error-space basis? + LOGICAL(c_bool), INTENT(out) :: fixedbasis + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + logical :: ensemblefilter_out, fixedbasis_out + call PDAF_enkf_init(subtype, param_int, dim_pint, param_real, dim_preal, & + ensemblefilter_out, fixedbasis_out, verbose, outflag) + ensemblefilter = ensemblefilter_out + fixedbasis = fixedbasis_out + END SUBROUTINE c__PDAF_enkf_init + + SUBROUTINE c__PDAF_enkf_alloc(outflag) bind(c) + use PDAF_enkf + implicit none + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + + call PDAF_enkf_alloc(outflag) + + END SUBROUTINE c__PDAF_enkf_alloc + + SUBROUTINE c__PDAF_enkf_config(subtype, verbose) bind(c) + use PDAF_enkf + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAF_enkf_config(subtype, verbose) + + END SUBROUTINE c__PDAF_enkf_config + + SUBROUTINE c__PDAF_enkf_set_iparam(id, value, flag) bind(c) + use PDAF_enkf + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + INTEGER(c_int), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_enkf_set_iparam(id, value, flag) + + END SUBROUTINE c__PDAF_enkf_set_iparam + + SUBROUTINE c__PDAF_enkf_set_rparam(id, value, flag) bind(c) + use PDAF_enkf + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + REAL(c_double), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_enkf_set_rparam(id, value, flag) + + END SUBROUTINE c__PDAF_enkf_set_rparam + + SUBROUTINE c__PDAF_enkf_options() bind(c) + use PDAF_enkf + implicit none + call PDAF_enkf_options() + + END SUBROUTINE c__PDAF_enkf_options + + SUBROUTINE c__PDAF_enkf_memtime(printtype) bind(c) + use PDAF_enkf + implicit none + ! Type of screen output: + INTEGER(c_int), INTENT(in) :: printtype + + + call PDAF_enkf_memtime(printtype) + + END SUBROUTINE c__PDAF_enkf_memtime + + SUBROUTINE c__PDAF_enkf_gather_resid(dim_obs, dim_obs_p, dim_ens, resid_p, & + resid) bind(c) + use PDAF_enkf + implicit none + ! Global observation dimension + INTEGER(c_int), INTENT(in) :: dim_obs + ! PE-local observation dimension + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local residual matrix + REAL(c_double), DIMENSION(dim_obs_p, dim_ens), INTENT(in) :: resid_p + ! Global residual matrix + REAL(c_double), DIMENSION(dim_obs, dim_ens), INTENT(out) :: resid + + + call PDAF_enkf_gather_resid(dim_obs, dim_obs_p, dim_ens, resid_p, resid) + + END SUBROUTINE c__PDAF_enkf_gather_resid + + SUBROUTINE c__PDAF_enkf_obs_ensemble(step, dim_obs_p, dim_obs, dim_ens, & + obsens_p, obs_p, u_init_obs_covar, screen, flag) bind(c) + use PDAF_enkf + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! Local dimension of current observation + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local obs. ensemble + REAL(c_double), DIMENSION(dim_obs_p,dim_ens), INTENT(out) :: obsens_p + ! PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Initialize observation error covariance matrix + procedure(c__init_obs_covar_pdaf) :: u_init_obs_covar + + init_obs_covar_pdaf_c_ptr => u_init_obs_covar + + call PDAF_enkf_obs_ensemble(step, dim_obs_p, dim_obs, dim_ens, obsens_p, & + obs_p, f__init_obs_covar_pdaf, screen, flag) + + END SUBROUTINE c__PDAF_enkf_obs_ensemble + + SUBROUTINE c__PDAFpf_update(step, dim_p, dim_obs_p, dim_ens, state_p, ainv, & + ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_likelihood, u_prepoststep, & + screen, subtype, flag) bind(c) + use PDAF_pf_update + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Inverse of matrix U + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(inout) :: ainv + ! PE-local ensemble matrix + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Filter subtype + INTEGER(c_int), INTENT(in) :: subtype + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Compute observation likelihood for an ensemble member + procedure(c__likelihood_pdaf) :: u_likelihood + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + call PDAFpf_update(step, dim_p, dim_obs_p, dim_ens, state_p, ainv, ens_p, & + u_init_dim_obs, u_obs_op, u_init_obs, u_likelihood, u_prepoststep, & + screen, subtype, flag) + + END SUBROUTINE c__PDAFpf_update + + SUBROUTINE c__PDAF_generate_rndmat(dim, rndmat, mattype) bind(c) + use PDAF_analysis_utils + implicit none + ! Size of matrix rndmat + INTEGER(c_int), INTENT(in) :: dim + ! Matrix + REAL(c_double), DIMENSION(dim, dim), INTENT(out) :: rndmat + ! Select type of random matrix: + INTEGER(c_int), INTENT(in) :: mattype + + + call PDAF_generate_rndmat(dim, rndmat, mattype) + + END SUBROUTINE c__PDAF_generate_rndmat + + SUBROUTINE c__PDAF_print_domain_stats(n_domains_p) bind(c) + use PDAF_analysis_utils + implicit none + ! Number of PE-local analysis domains + INTEGER(c_int), INTENT(in) :: n_domains_p + + + call PDAF_print_domain_stats(n_domains_p) + + END SUBROUTINE c__PDAF_print_domain_stats + + SUBROUTINE c__PDAF_init_local_obsstats() bind(c) + use PDAF_analysis_utils + implicit none + call PDAF_init_local_obsstats() + + END SUBROUTINE c__PDAF_init_local_obsstats + + SUBROUTINE c__PDAF_incr_local_obsstats(dim_obs_l) bind(c) + use PDAF_analysis_utils + implicit none + ! Number of locally assimilated observations + INTEGER(c_int), INTENT(in) :: dim_obs_l + + + call PDAF_incr_local_obsstats(dim_obs_l) + + END SUBROUTINE c__PDAF_incr_local_obsstats + + SUBROUTINE c__PDAF_print_local_obsstats(screen, n_domains_with_obs) bind(c) + use PDAF_analysis_utils + implicit none + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! + INTEGER(c_int), INTENT(out) :: n_domains_with_obs + + + call PDAF_print_local_obsstats(screen, n_domains_with_obs) + + END SUBROUTINE c__PDAF_print_local_obsstats + + SUBROUTINE c__PDAF_seik_matrixT(dim, dim_ens, a) bind(c) + use PDAF_analysis_utils + implicit none + ! dimension of states + INTEGER(c_int), INTENT(in) :: dim + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Input/output matrix + REAL(c_double), DIMENSION(dim, dim_ens), INTENT(inout) :: a + + + call PDAF_seik_matrixT(dim, dim_ens, a) + + END SUBROUTINE c__PDAF_seik_matrixT + + SUBROUTINE c__PDAF_seik_TtimesA(rank, dim_col, a, b) bind(c) + use PDAF_analysis_utils + implicit none + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: rank + ! Number of columns in A and B + INTEGER(c_int), INTENT(in) :: dim_col + ! Input matrix + REAL(c_double), DIMENSION(rank, dim_col), INTENT(in) :: a + ! Output matrix (TA) + REAL(c_double), DIMENSION(rank+1, dim_col), INTENT(out) :: b + + + call PDAF_seik_TtimesA(rank, dim_col, a, b) + + END SUBROUTINE c__PDAF_seik_TtimesA + + SUBROUTINE c__PDAF_seik_Omega(rank, omega, omegatype, screen) bind(c) + use PDAF_analysis_utils + implicit none + ! Approximated rank of covar matrix + INTEGER(c_int), INTENT(in) :: rank + ! Matrix Omega + REAL(c_double), DIMENSION(rank+1, rank), INTENT(inout) :: omega + ! Select type of Omega: + INTEGER(c_int), INTENT(in) :: omegatype + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + + call PDAF_seik_Omega(rank, omega, omegatype, screen) + + END SUBROUTINE c__PDAF_seik_Omega + + SUBROUTINE c__PDAF_seik_Uinv(rank, uinv) bind(c) + use PDAF_analysis_utils + implicit none + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: rank + ! Inverse of matrix U + REAL(c_double), DIMENSION(rank, rank), INTENT(inout) :: uinv + + + call PDAF_seik_Uinv(rank, uinv) + + END SUBROUTINE c__PDAF_seik_Uinv + + SUBROUTINE c__PDAF_ens_Omega(seed, r, dim_ens, omega, norm, otype, & + screen) bind(c) + use PDAF_analysis_utils + implicit none + ! Seed for random number generation + INTEGER(c_int), DIMENSION(4), INTENT(in) :: seed + ! Approximated rank of covar matrix + INTEGER(c_int), INTENT(in) :: r + ! Ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! Random matrix + REAL(c_double), DIMENSION(dim_ens,r), INTENT(inout) :: omega + ! Norm for ensemble transformation + REAL(c_double), INTENT(inout) :: norm + ! Type of Omega: + INTEGER(c_int), INTENT(in) :: otype + ! Control verbosity + INTEGER(c_int), INTENT(in) :: screen + + + call PDAF_ens_Omega(seed, r, dim_ens, omega, norm, otype, screen) + + END SUBROUTINE c__PDAF_ens_Omega + + SUBROUTINE c__PDAF_estkf_OmegaA(rank, dim_col, a, b) bind(c) + use PDAF_analysis_utils + implicit none + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: rank + ! Number of columns in A and B + INTEGER(c_int), INTENT(in) :: dim_col + ! Input matrix + REAL(c_double), DIMENSION(rank, dim_col), INTENT(in) :: a + ! Output matrix (TA) + REAL(c_double), DIMENSION(rank+1, dim_col), INTENT(out) :: b + + + call PDAF_estkf_OmegaA(rank, dim_col, a, b) + + END SUBROUTINE c__PDAF_estkf_OmegaA + + SUBROUTINE c__PDAF_estkf_AOmega(dim, dim_ens, a) bind(c) + use PDAF_analysis_utils + implicit none + ! dimension of states + INTEGER(c_int), INTENT(in) :: dim + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Input/output matrix + REAL(c_double), DIMENSION(dim, dim_ens), INTENT(inout) :: a + + + call PDAF_estkf_AOmega(dim, dim_ens, a) + + END SUBROUTINE c__PDAF_estkf_AOmega + + SUBROUTINE c__PDAF_subtract_rowmean(dim, dim_ens, a) bind(c) + use PDAF_analysis_utils + implicit none + ! dimension of states + INTEGER(c_int), INTENT(in) :: dim + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Input/output matrix + REAL(c_double), DIMENSION(dim, dim_ens), INTENT(inout) :: a + + + call PDAF_subtract_rowmean(dim, dim_ens, a) + + END SUBROUTINE c__PDAF_subtract_rowmean + + SUBROUTINE c__PDAF_subtract_colmean(dim_ens, dim, a) bind(c) + use PDAF_analysis_utils + implicit none + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: dim_ens + ! Number of columns in A and B + INTEGER(c_int), INTENT(in) :: dim + ! Input/output matrix + REAL(c_double), DIMENSION(dim_ens, dim), INTENT(inout) :: a + + + call PDAF_subtract_colmean(dim_ens, dim, a) + + END SUBROUTINE c__PDAF_subtract_colmean + + SUBROUTINE c__PDAF_add_particle_noise(dim_p, dim_ens, state_p, ens_p, & + type_noise, noise_amp, screen) bind(c) + use PDAF_analysis_utils + implicit none + ! State dimension + INTEGER(c_int), INTENT(in) :: dim_p + ! Number of particles + INTEGER(c_int), INTENT(in) :: dim_ens + ! State vector (not filled) + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Ensemble array + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Type of noise + INTEGER(c_int), INTENT(in) :: type_noise + ! Noise amplitude + REAL(c_double), INTENT(in) :: noise_amp + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + + call PDAF_add_particle_noise(dim_p, dim_ens, state_p, ens_p, type_noise, & + noise_amp, screen) + + END SUBROUTINE c__PDAF_add_particle_noise + + SUBROUTINE c__PDAF_inflate_weights(screen, dim_ens, alpha, weights) bind(c) + use PDAF_analysis_utils + implicit none + ! verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! Minimum limit of n_eff / N + REAL(c_double), INTENT(in) :: alpha + ! weights (before and after inflation) + REAL(c_double), DIMENSION(dim_ens), INTENT(inout) :: weights + + + call PDAF_inflate_weights(screen, dim_ens, alpha, weights) + + END SUBROUTINE c__PDAF_inflate_weights + + SUBROUTINE c__PDAF_inflate_ens(dim, dim_ens, meanstate, ens, forget, & + do_ensmean) bind(c) + use PDAF_analysis_utils + implicit none + ! dimension of states + INTEGER(c_int), INTENT(in) :: dim + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! state vector to hold ensemble mean + REAL(c_double), DIMENSION(dim), INTENT(inout) :: meanstate + ! Input/output ensemble matrix + REAL(c_double), DIMENSION(dim, dim_ens), INTENT(inout) :: ens + ! Forgetting factor + REAL(c_double), INTENT(in) :: forget + ! Whether to compute the ensemble mean state + LOGICAL(c_bool), INTENT(in) :: do_ensmean + + call PDAF_inflate_ens(dim, dim_ens, meanstate, ens, forget, logical(do_ensmean)) + + END SUBROUTINE c__PDAF_inflate_ens + + SUBROUTINE c__PDAF_alloc(dim_p, dim_ens, dim_ens_task, dim_es, & + statetask, outflag) bind(c) + use pdaf_utils + implicit none + ! Size of state vector + INTEGER(c_int), INTENT(in) :: dim_p + ! Ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + ! Ensemble size handled by a model task + INTEGER(c_int), INTENT(in) :: dim_ens_task + ! Dimension of error space (size of Ainv) + INTEGER(c_int), INTENT(in) :: dim_es + ! Task ID forecasting a single state + INTEGER(c_int), INTENT(in) :: statetask + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + + call PDAF_alloc(dim_p, dim_ens, dim_ens_task, dim_es, statetask, outflag) + + END SUBROUTINE c__PDAF_alloc + + SUBROUTINE c__PDAF_alloc_sens(dim_p, dim_ens, dim_lag, outflag) bind(c) + use PDAF_utils, only: PDAF_alloc_sens + IMPLICIT NONE + !< Size of state vector + INTEGER(c_int), INTENT(in) :: dim_p + !< Ensemble size + INTEGER(c_int), INTENT(in) :: dim_ens + !< Smoother lag + INTEGER(c_int), INTENT(in) :: dim_lag + !< Status flag + INTEGER(c_int), INTENT(inout):: outflag + + call PDAF_alloc_sens(dim_p, dim_ens, dim_lag, outflag) + END SUBROUTINE c__PDAF_alloc_sens + + SUBROUTINE c__PDAF_alloc_bias(dim_bias_p, outflag) bind(c) + use PDAF_utils, only: PDAF_alloc_bias + IMPLICIT NONE + !< Size of bias vector + INTEGER(c_int), INTENT(in) :: dim_bias_p + !< Status flag + INTEGER(c_int), INTENT(inout):: outflag + + call PDAF_alloc_bias(dim_bias_p, outflag) + END SUBROUTINE c__PDAF_alloc_bias + + SUBROUTINE c__PDAF_smoothing(dim_p, dim_ens, dim_lag, ainv, sens_p, & + cnt_maxlag, forget, screen) bind(c) + use PDAF_smoother + implicit none + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Number of past time instances for smoother + INTEGER(c_int), INTENT(in) :: dim_lag + ! Weight matrix for ensemble transformation + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(in) :: ainv + ! PE-local smoother ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens, dim_lag), INTENT(inout) :: sens_p + ! Count available number of time steps for smoothing + INTEGER(c_int), INTENT(inout) :: cnt_maxlag + ! Forgetting factor + REAL(c_double), INTENT(in) :: forget + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + + call PDAF_smoothing(dim_p, dim_ens, dim_lag, ainv, sens_p, cnt_maxlag, & + forget, screen) + + END SUBROUTINE c__PDAF_smoothing + + SUBROUTINE c__PDAF_smoothing_local(domain_p, step, dim_p, dim_l, dim_ens, & + dim_lag, ainv, ens_l, sens_p, cnt_maxlag, u_g2l_state, u_l2g_state, & + forget, screen) bind(c) + use PDAF_smoother + implicit none + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! State dimension on local analysis domain + INTEGER(c_int), INTENT(in) :: dim_l + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Number of past time instances for smoother + INTEGER(c_int), INTENT(in) :: dim_lag + ! Weight matrix for ensemble transformation + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(in) :: ainv + ! local past ensemble (temporary) + REAL(c_double), DIMENSION(dim_l, dim_ens), INTENT(inout) :: ens_l + ! PE-local smoother ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens, dim_lag), INTENT(inout) :: sens_p + ! Count available number of time steps for smoothing + INTEGER(c_int), INTENT(inout) :: cnt_maxlag + ! Forgetting factor + REAL(c_double), INTENT(in) :: forget + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + ! Get state on local ana. domain from global state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + + call PDAF_smoothing_local(domain_p, step, dim_p, dim_l, dim_ens, dim_lag, & + ainv, ens_l, sens_p, cnt_maxlag, f__g2l_state_pdaf, f__l2g_state_pdaf, forget, screen) + + END SUBROUTINE c__PDAF_smoothing_local + + SUBROUTINE c__PDAF_smoother_shift(dim_p, dim_ens, dim_lag, ens_p, sens_p, & + cnt_maxlag, screen) bind(c) + use PDAF_smoother + implicit none + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Number of past time instances for smoother + INTEGER(c_int), INTENT(in) :: dim_lag + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens, 1), INTENT(inout) :: ens_p + ! PE-local smoother ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens, dim_lag), INTENT(inout) :: sens_p + ! Count available number of time steps for smoothing + INTEGER(c_int), INTENT(inout) :: cnt_maxlag + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + + call PDAF_smoother_shift(dim_p, dim_ens, dim_lag, ens_p, sens_p, & + cnt_maxlag, screen) + + END SUBROUTINE c__PDAF_smoother_shift + + SUBROUTINE c__PDAFlknetf_update_sync(step, dim_p, dim_obs_f, dim_ens, & + state_p, ainv, ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_init_obs_l, & + u_prodrinva_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + u_likelihood_l, u_prepoststep, screen, subtype, flag) bind(c) + use PDAF_lknetf_update_sync + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_f + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Inverse of matrix U + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(inout) :: ainv + ! PE-local ensemble matrix + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Filter subtype + INTEGER(c_int), INTENT(in) :: subtype + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! Compute product of R^(-1) with HV + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from global state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! Compute likelihood + procedure(c__likelihood_l_pdaf) :: u_likelihood_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + call PDAFlknetf_update_sync(step, dim_p, dim_obs_f, dim_ens, state_p, & + ainv, ens_p, u_init_dim_obs, u_obs_op, u_init_obs, u_init_obs_l, & + u_prodrinva_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + u_likelihood_l, u_prepoststep, screen, subtype, flag) + + END SUBROUTINE c__PDAFlknetf_update_sync + + SUBROUTINE c__PDAF_etkf_ana(step, dim_p, dim_obs_p, dim_ens, state_p, ainv, & + ens_p, hz_p, hxbar_p, obs_p, forget, u_prodrinva, screen, type_trans, & + debug, flag) bind(c) + use PDAF_etkf_analysis + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! on exit: PE-local forecast state + REAL(c_double), DIMENSION(dim_p), INTENT(out) :: state_p + ! on exit: weight matrix for ensemble transformation + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(out) :: ainv + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! PE-local observed ensemble + REAL(c_double), DIMENSION(dim_obs_p, dim_ens), INTENT(inout) :: hz_p + ! PE-local observed state + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: hxbar_p + ! PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Forgetting factor + REAL(c_double), INTENT(in) :: forget + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Type of ensemble transformation + INTEGER(c_int), INTENT(in) :: type_trans + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + + prodrinva_pdaf_c_ptr => u_prodrinva + + call PDAF_etkf_ana(step, dim_p, dim_obs_p, dim_ens, state_p, ainv, ens_p, & + hz_p, hxbar_p, obs_p, forget, f__prodrinva_pdaf, screen, type_trans, debug, & + flag) + + END SUBROUTINE c__PDAF_etkf_ana + + SUBROUTINE c__PDAF_letkf_ana(domain_p, step, dim_l, dim_obs_l, dim_ens, & + state_l, ainv_l, ens_l, hz_l, hxbar_l, obs_l, rndmat, forget, & + u_prodrinva_l, type_trans, screen, debug, flag) bind(c) + use PDAF_letkf_analysis + implicit none + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! State dimension on local analysis domain + INTEGER(c_int), INTENT(in) :: dim_l + ! Size of obs. vector on local ana. domain + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Local forecast state + REAL(c_double), DIMENSION(dim_l), INTENT(inout) :: state_l + ! on exit: local weight matrix for ensemble transformation + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(out) :: ainv_l + ! Local state ensemble + REAL(c_double), DIMENSION(dim_l, dim_ens), INTENT(inout) :: ens_l + ! Local observed state ensemble (perturbation) + REAL(c_double), DIMENSION(dim_obs_l, dim_ens), INTENT(inout) :: hz_l + ! Local observed ensemble mean + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: hxbar_l + ! Local observation vector + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: obs_l + ! Global random rotation matrix + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(inout) :: rndmat + ! Forgetting factor + REAL(c_double), INTENT(inout) :: forget + ! Type of ensemble transformation + INTEGER(c_int), INTENT(in) :: type_trans + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Provide product R^-1 A for local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + + call PDAF_letkf_ana(domain_p, step, dim_l, dim_obs_l, dim_ens, state_l, & + ainv_l, ens_l, hz_l, hxbar_l, obs_l, rndmat, forget, f__prodrinva_l_pdaf, & + type_trans, screen, debug, flag) + + END SUBROUTINE c__PDAF_letkf_ana + + SUBROUTINE c__PDAF_letkf_init(subtype, param_int, dim_pint, param_real, & + dim_preal, ensemblefilter, fixedbasis, verbose, outflag) bind(c) + use PDAF_letkf + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Number of integer parameters + INTEGER(c_int), INTENT(in) :: dim_pint + ! Integer parameter array + INTEGER(c_int), DIMENSION(dim_pint), INTENT(inout) :: param_int + ! Number of real parameters + INTEGER(c_int), INTENT(in) :: dim_preal + ! Real parameter array + REAL(c_double), DIMENSION(dim_preal), INTENT(inout) :: param_real + ! Is the chosen filter ensemble-based? + LOGICAL(c_bool), INTENT(out) :: ensemblefilter + ! Does the filter run with fixed error-space basis? + LOGICAL(c_bool), INTENT(out) :: fixedbasis + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + logical :: ensemblefilter_out, fixedbasis_out + + call PDAF_letkf_init(subtype, param_int, dim_pint, param_real, dim_preal, & + ensemblefilter_out, fixedbasis_out, verbose, outflag) + ensemblefilter = ensemblefilter_out + fixedbasis = fixedbasis_out + END SUBROUTINE c__PDAF_letkf_init + + SUBROUTINE c__PDAF_letkf_alloc(outflag) bind(c) + use PDAF_letkf + implicit none + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + + call PDAF_letkf_alloc(outflag) + + END SUBROUTINE c__PDAF_letkf_alloc + + SUBROUTINE c__PDAF_letkf_config(subtype, verbose) bind(c) + use PDAF_letkf + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAF_letkf_config(subtype, verbose) + + END SUBROUTINE c__PDAF_letkf_config + + SUBROUTINE c__PDAF_letkf_set_iparam(id, value, flag) bind(c) + use PDAF_letkf + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + INTEGER(c_int), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_letkf_set_iparam(id, value, flag) + + END SUBROUTINE c__PDAF_letkf_set_iparam + + SUBROUTINE c__PDAF_letkf_set_rparam(id, value, flag) bind(c) + use PDAF_letkf + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + REAL(c_double), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_letkf_set_rparam(id, value, flag) + + END SUBROUTINE c__PDAF_letkf_set_rparam + + SUBROUTINE c__PDAF_letkf_options() bind(c) + use PDAF_letkf + implicit none + call PDAF_letkf_options() + + END SUBROUTINE c__PDAF_letkf_options + + SUBROUTINE c__PDAF_letkf_memtime(printtype) bind(c) + use PDAF_letkf + implicit none + ! Type of screen output: + INTEGER(c_int), INTENT(in) :: printtype + + + call PDAF_letkf_memtime(printtype) + + END SUBROUTINE c__PDAF_letkf_memtime + + SUBROUTINE c__PDAF_estkf_ana(step, dim_p, dim_obs_p, dim_ens, rank, state_p, & + ainv, ens_p, hl_p, hxbar_p, obs_p, forget, u_prodrinva, screen, & + envar_mode, type_sqrt, type_trans, ta, debug, flag) bind(c) + use PDAF_estkf_analysis + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(inout) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: rank + ! on exit: PE-local forecast mean state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Inverse of matrix A - temporary use only + REAL(c_double), DIMENSION(rank, rank), INTENT(inout) :: ainv + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! PE-local observed ensemble + REAL(c_double), DIMENSION(dim_obs_p, dim_ens), INTENT(inout) :: hl_p + ! PE-local observed state + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: hxbar_p + ! PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Forgetting factor + REAL(c_double), INTENT(in) :: forget + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Flag whether routine is called from 3DVar for special functionality + INTEGER(c_int), INTENT(in) :: envar_mode + ! Type of square-root of A + INTEGER(c_int), INTENT(in) :: type_sqrt + ! Type of ensemble transformation + INTEGER(c_int), INTENT(in) :: type_trans + ! Ensemble transformation matrix + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(inout) :: ta + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Provide product R^-1 with some matrix + procedure(c__prodrinva_pdaf) :: u_prodrinva + + prodrinva_pdaf_c_ptr => u_prodrinva + + call PDAF_estkf_ana(step, dim_p, dim_obs_p, dim_ens, rank, state_p, ainv, & + ens_p, hl_p, hxbar_p, obs_p, forget, f__prodrinva_pdaf, screen, envar_mode, & + type_sqrt, type_trans, ta, debug, flag) + + END SUBROUTINE c__PDAF_estkf_ana + + SUBROUTINE c__PDAF_ensrf_ana(step, dim_p, dim_obs_p, dim_ens, state_p, & + ens_p, hx_p, hxbar_p, obs_p, var_obs_p, u_localize_covar_serial, screen, & + debug) bind(c) + use PDAF_ensrf_analysis + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Size of state ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local ensemble mean state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! PE-local observed ensemble + REAL(c_double), DIMENSION(dim_obs_p, dim_ens), INTENT(inout) :: hx_p + ! PE-local observed state + REAL(c_double), DIMENSION(dim_obs_p), INTENT(inout) :: hxbar_p + ! PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! PE-local vector of observation eror variances + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: var_obs_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + + ! Apply localization for single-observation vectors + procedure(c__localize_covar_serial_pdaf) :: u_localize_covar_serial + + localize_covar_serial_pdaf_c_ptr => u_localize_covar_serial + + call PDAF_ensrf_ana(step, dim_p, dim_obs_p, dim_ens, state_p, ens_p, & + hx_p, hxbar_p, obs_p, var_obs_p, f__localize_covar_serial_pdaf, screen, debug) + + END SUBROUTINE c__PDAF_ensrf_ana + + SUBROUTINE c__PDAF_ensrf_ana_2step(step, dim_p, dim_obs_p, dim_ens, state_p, & + ens_p, hx_p, hxbar_p, obs_p, var_obs_p, u_localize_covar_serial, screen, & + debug) bind(c) + use PDAF_ensrf_analysis + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Size of state ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local ensemble mean state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! PE-local observed ensemble + REAL(c_double), DIMENSION(dim_obs_p, dim_ens), INTENT(inout) :: hx_p + ! PE-local observed state + REAL(c_double), DIMENSION(dim_obs_p), INTENT(inout) :: hxbar_p + ! PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! PE-local vector of observation eror variances + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: var_obs_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + + ! Apply localization for single-observation vectors + procedure(c__localize_covar_serial_pdaf) :: u_localize_covar_serial + + localize_covar_serial_pdaf_c_ptr => u_localize_covar_serial + + call PDAF_ensrf_ana_2step(step, dim_p, dim_obs_p, dim_ens, state_p, & + ens_p, hx_p, hxbar_p, obs_p, var_obs_p, f__localize_covar_serial_pdaf, & + screen, debug) + + END SUBROUTINE c__PDAF_ensrf_ana_2step + + SUBROUTINE c__PDAFlnetf_update(step, dim_p, dim_obs_f, dim_ens, state_p, & + ainv, ens_p, u_obs_op, u_init_dim_obs, u_init_obs, u_init_obs_l, & + u_likelihood_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_prepoststep, screen, subtype, & + dim_lag, sens_p, cnt_maxlag, flag) bind(c) + use PDAF_lnetf_update + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_f + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Inverse of matrix U + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(inout) :: ainv + ! PE-local ensemble matrix + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Filter subtype + INTEGER(c_int), INTENT(in) :: subtype + ! Status flag + INTEGER(c_int), INTENT(inout) :: dim_lag + ! PE-local smoother ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens, dim_lag), INTENT(inout) :: sens_p + ! Count number of past time steps for smoothing + INTEGER(c_int), INTENT(inout) :: cnt_maxlag + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! Compute observation likelihood for an ensemble member + procedure(c__likelihood_l_pdaf) :: u_likelihood_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from global state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + call PDAFlnetf_update(step, dim_p, dim_obs_f, dim_ens, state_p, ainv, & + ens_p, u_obs_op, u_init_dim_obs, u_init_obs, u_init_obs_l, & + u_likelihood_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_prepoststep, screen, subtype, & + dim_lag, sens_p, cnt_maxlag, flag) + + END SUBROUTINE c__PDAFlnetf_update + + SUBROUTINE c__PDAF_seik_ana_trans(step, dim_p, dim_obs_p, dim_ens, rank, & + state_p, uinv, ens_p, hl_p, hxbar_p, obs_p, forget, u_prodrinva, screen, & + type_sqrt, type_trans, nm1vsn, debug, flag) bind(c) + use PDAF_seik_analysis_trans + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: rank + ! PE-local forecast mean state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Inverse of matrix U - temporary use only + REAL(c_double), DIMENSION(rank, rank), INTENT(inout) :: uinv + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! PE-local observed ensemble (perturbations) + REAL(c_double), DIMENSION(dim_obs_p, dim_ens), INTENT(inout) :: hl_p + ! PE-local observed state + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: hxbar_p + ! PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Forgetting factor + REAL(c_double), INTENT(in) :: forget + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Type of square-root of A + INTEGER(c_int), INTENT(in) :: type_sqrt + ! Type of ensemble transformation + INTEGER(c_int), INTENT(in) :: type_trans + ! Type of normalization in covariance matrix computation + INTEGER(c_int), INTENT(in) :: nm1vsn + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + + prodrinva_pdaf_c_ptr => u_prodrinva + + call PDAF_seik_ana_trans(step, dim_p, dim_obs_p, dim_ens, rank, state_p, & + uinv, ens_p, hl_p, hxbar_p, obs_p, forget, f__prodrinva_pdaf, screen, & + type_sqrt, type_trans, nm1vsn, debug, flag) + + END SUBROUTINE c__PDAF_seik_ana_trans + + SUBROUTINE c__PDAFhyb3dvar_update_estkf(step, dim_p, dim_obs_p, dim_ens, & + dim_cvec, dim_cvec_ens, state_p, ainv, ens_p, u_init_dim_obs, u_obs_op, & + u_init_obs, u_prodrinva, u_prepoststep, u_cvt_ens, u_cvt_adj_ens, u_cvt, & + u_cvt_adj, u_obs_op_lin, u_obs_op_adj, u_init_obsvar, screen, flag) bind(c) + use PDAF_hyb3dvar_update + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Size of control vector (parameterized part) + INTEGER(c_int), INTENT(in) :: dim_cvec + ! Size of control vector (ensemble part) + INTEGER(c_int), INTENT(in) :: dim_cvec_ens + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Transform matrix + REAL(c_double), DIMENSION(dim_ens-1, dim_ens-1), INTENT(inout) :: ainv + ! PE-local ensemble matrix + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A for 3DVAR analysis + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Apply control vector transform matrix (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble var) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Apply control vector transform matrix + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + + call PDAFhyb3dvar_update_estkf(step, dim_p, dim_obs_p, dim_ens, dim_cvec, & + dim_cvec_ens, state_p, ainv, ens_p, u_init_dim_obs, u_obs_op, & + u_init_obs, u_prodrinva, u_prepoststep, u_cvt_ens, u_cvt_adj_ens, & + u_cvt, u_cvt_adj, u_obs_op_lin, u_obs_op_adj, u_init_obsvar, screen, & + flag) + + END SUBROUTINE c__PDAFhyb3dvar_update_estkf + + SUBROUTINE c__PDAFhyb3dvar_update_lestkf(step, dim_p, dim_obs_p, dim_ens, & + dim_cvec, dim_cvec_ens, state_p, ainv, ens_p, u_init_dim_obs, u_obs_op, & + u_init_obs, u_prodrinva, u_prepoststep, u_cvt_ens, u_cvt_adj_ens, u_cvt, & + u_cvt_adj, u_obs_op_lin, u_obs_op_adj, u_init_dim_obs_f, u_obs_op_f, & + u_init_obs_f, u_init_obs_l, u_prodrinva_l, u_init_n_domains_p, & + u_init_dim_l, u_init_dim_obs_l, u_g2l_state, u_l2g_state, u_g2l_obs, & + u_init_obsvar, u_init_obsvar_l, screen, flag) bind(c) + use PDAF_hyb3dvar_update + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(out) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Size of control vector (parameterized part) + INTEGER(c_int), INTENT(in) :: dim_cvec + ! Size of control vector (ensemble part) + INTEGER(c_int), INTENT(in) :: dim_cvec_ens + ! PE-local model state + REAL(c_double), DIMENSION(dim_p), INTENT(inout) :: state_p + ! Transform matrix for LESKTF + REAL(c_double), DIMENSION(dim_ens-1, dim_ens-1), INTENT(inout) :: ainv + ! PE-local ensemble matrix + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A for 3DVAR analysis + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Apply control vector transform matrix (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble var) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Apply control vector transform matrix + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs_f + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_f + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs_f + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + + call PDAFhyb3dvar_update_lestkf(step, dim_p, dim_obs_p, dim_ens, & + dim_cvec, dim_cvec_ens, state_p, ainv, ens_p, u_init_dim_obs, & + u_obs_op, u_init_obs, u_prodrinva, u_prepoststep, u_cvt_ens, & + u_cvt_adj_ens, u_cvt, u_cvt_adj, u_obs_op_lin, u_obs_op_adj, & + u_init_dim_obs_f, u_obs_op_f, u_init_obs_f, u_init_obs_l, & + u_prodrinva_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + screen, flag) + + END SUBROUTINE c__PDAFhyb3dvar_update_lestkf + + SUBROUTINE c__PDAF_lestkf_ana_fixed(domain_p, step, dim_l, dim_obs_l, & + dim_ens, rank, state_l, ainv_l, ens_l, hl_l, hxbar_l, obs_l, forget, & + u_prodrinva_l, type_sqrt, screen, debug, flag) bind(c) + use PDAF_lestkf_analysis_fixed + implicit none + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! State dimension on local analysis domain + INTEGER(c_int), INTENT(in) :: dim_l + ! Size of obs. vector on local ana. domain + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: rank + ! state on local analysis domain + REAL(c_double), DIMENSION(dim_l), INTENT(inout) :: state_l + ! Inverse of matrix U - temporary use only + REAL(c_double), DIMENSION(rank, rank), INTENT(inout) :: ainv_l + ! Local state ensemble + REAL(c_double), DIMENSION(dim_l, dim_ens), INTENT(inout) :: ens_l + ! Local observed state ensemble (perturbation) + REAL(c_double), DIMENSION(dim_obs_l, dim_ens), INTENT(inout) :: hl_l + ! Local observed ensemble mean + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: hxbar_l + ! Local observation vector + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: obs_l + ! Forgetting factor + REAL(c_double), INTENT(inout) :: forget + ! Type of square-root of A + INTEGER(c_int), INTENT(in) :: type_sqrt + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Provide product R^-1 A for local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + + call PDAF_lestkf_ana_fixed(domain_p, step, dim_l, dim_obs_l, dim_ens, & + rank, state_l, ainv_l, ens_l, hl_l, hxbar_l, obs_l, forget, & + f__prodrinva_l_pdaf, type_sqrt, screen, debug, flag) + + END SUBROUTINE c__PDAF_lestkf_ana_fixed + + SUBROUTINE c__PDAF_genobs_init(subtype, param_int, dim_pint, param_real, & + dim_preal, ensemblefilter, fixedbasis, verbose, outflag) bind(c) + use PDAF_genobs + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(in) :: subtype + ! Number of integer parameters + INTEGER(c_int), INTENT(in) :: dim_pint + ! Integer parameter array + INTEGER(c_int), DIMENSION(dim_pint), INTENT(inout) :: param_int + ! Number of real parameters + INTEGER(c_int), INTENT(in) :: dim_preal + ! Real parameter array + REAL(c_double), DIMENSION(dim_preal), INTENT(inout) :: param_real + ! Is the chosen filter ensemble-based? + LOGICAL(c_bool), INTENT(out) :: ensemblefilter + ! Does the filter run with fixed error-space basis? + LOGICAL(c_bool), INTENT(out) :: fixedbasis + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + logical :: ensemblefilter_out, fixedbasis_out + + call PDAF_genobs_init(subtype, param_int, dim_pint, param_real, & + dim_preal, ensemblefilter_out, fixedbasis_out, verbose, outflag) + ensemblefilter = ensemblefilter_out + fixedbasis = fixedbasis_out + END SUBROUTINE c__PDAF_genobs_init + + SUBROUTINE c__PDAF_genobs_alloc(outflag) bind(c) + use PDAF_genobs + implicit none + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + + call PDAF_genobs_alloc(outflag) + + END SUBROUTINE c__PDAF_genobs_alloc + + SUBROUTINE c__PDAF_genobs_config(subtype, verbose) bind(c) + use PDAF_genobs + implicit none + ! Sub-type of filter + INTEGER(c_int), INTENT(inout) :: subtype + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAF_genobs_config(subtype, verbose) + + END SUBROUTINE c__PDAF_genobs_config + + SUBROUTINE c__PDAF_genobs_set_iparam(id, value, flag) bind(c) + use PDAF_genobs + implicit none + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + INTEGER(c_int), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(out) :: flag + + + call PDAF_genobs_set_iparam(id, value, flag) + + END SUBROUTINE c__PDAF_genobs_set_iparam + + SUBROUTINE c__PDAF_genobs_options() bind(c) + use PDAF_genobs + implicit none + call PDAF_genobs_options() + + END SUBROUTINE c__PDAF_genobs_options + + SUBROUTINE c__PDAF_etkf_ana_T(step, dim_p, dim_obs_p, dim_ens, state_p, & + ainv, ens_p, hz_p, hxbar_p, obs_p, forget, u_prodrinva, screen, & + type_trans, debug, flag) bind(c) + use PDAF_etkf_analysis_T + implicit none + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! PE-local dimension of model state + INTEGER(c_int), INTENT(in) :: dim_p + ! PE-local dimension of observation vector + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! on exit: PE-local forecast state + REAL(c_double), DIMENSION(dim_p), INTENT(out) :: state_p + ! on exit: weight matrix for ensemble transformation + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(out) :: ainv + ! PE-local state ensemble + REAL(c_double), DIMENSION(dim_p, dim_ens), INTENT(inout) :: ens_p + ! PE-local observed ensemble + REAL(c_double), DIMENSION(dim_obs_p, dim_ens), INTENT(inout) :: hz_p + ! PE-local observed state + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: hxbar_p + ! PE-local observation vector + REAL(c_double), DIMENSION(dim_obs_p), INTENT(in) :: obs_p + ! Forgetting factor + REAL(c_double), INTENT(in) :: forget + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Type of ensemble transformation + INTEGER(c_int), INTENT(in) :: type_trans + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + + prodrinva_pdaf_c_ptr => u_prodrinva + + call PDAF_etkf_ana_T(step, dim_p, dim_obs_p, dim_ens, state_p, ainv, & + ens_p, hz_p, hxbar_p, obs_p, forget, f__prodrinva_pdaf, screen, type_trans, & + debug, flag) + + END SUBROUTINE c__PDAF_etkf_ana_T + + SUBROUTINE c__PDAF_letkf_ana_fixed(domain_p, step, dim_l, dim_obs_l, & + dim_ens, state_l, ainv_l, ens_l, hz_l, hxbar_l, obs_l, forget, & + u_prodrinva_l, screen, debug, flag) bind(c) + use PDAF_letkf_analysis_fixed + implicit none + ! Current local analysis domain + INTEGER(c_int), INTENT(in) :: domain_p + ! Current time step + INTEGER(c_int), INTENT(in) :: step + ! State dimension on local analysis domain + INTEGER(c_int), INTENT(in) :: dim_l + ! Size of obs. vector on local ana. domain + INTEGER(c_int), INTENT(in) :: dim_obs_l + ! Size of ensemble + INTEGER(c_int), INTENT(in) :: dim_ens + ! Local forecast state + REAL(c_double), DIMENSION(dim_l), INTENT(inout) :: state_l + ! on exit: local weight matrix for ensemble transformation + REAL(c_double), DIMENSION(dim_ens, dim_ens), INTENT(out) :: ainv_l + ! Local state ensemble + REAL(c_double), DIMENSION(dim_l, dim_ens), INTENT(inout) :: ens_l + ! Local observed state ensemble (perturbation) + REAL(c_double), DIMENSION(dim_obs_l, dim_ens), INTENT(inout) :: hz_l + ! Local observed ensemble mean + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: hxbar_l + ! Local observation vector + REAL(c_double), DIMENSION(dim_obs_l), INTENT(in) :: obs_l + ! Forgetting factor + REAL(c_double), INTENT(inout) :: forget + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + ! Flag for writing debug output + INTEGER(c_int), INTENT(in) :: debug + ! Status flag + INTEGER(c_int), INTENT(inout) :: flag + + ! Provide product R^-1 A for local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + + call PDAF_letkf_ana_fixed(domain_p, step, dim_l, dim_obs_l, dim_ens, & + state_l, ainv_l, ens_l, hz_l, hxbar_l, obs_l, forget, f__prodrinva_l_pdaf, & + screen, debug, flag) + + END SUBROUTINE c__PDAF_letkf_ana_fixed +end module pdaf_c_internal + diff --git a/pyPDAF/source/src/fortran/pdaf_c_put.f90 b/pyPDAF/source/src/fortran/pdaf_c_put.f90 new file mode 100644 index 0000000000000000000000000000000000000000..5afa639b96c7f925a79e89acd49abc43aede436a --- /dev/null +++ b/pyPDAF/source/src/fortran/pdaf_c_put.f90 @@ -0,0 +1,963 @@ +MODULE pdaf_c_put +use iso_c_binding, only: c_int, c_double, c_bool +use PDAF +use pdaf_c_cb_interface +use pdaf_c_f_interface + +implicit none + +contains + SUBROUTINE c__PDAF_put_state_lestkf(u_collect_state, u_init_dim_obs, & + u_obs_op, u_init_obs, u_init_obs_l, u_prepoststep, u_prodrinva_l, & + u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, u_g2l_state, & + u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + + call PDAF_put_state_lestkf(f__collect_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__init_obs_l_pdaf, f__prepoststep_pdaf, f__prodrinva_l_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, & + f__l2g_state_pdaf, f__g2l_obs_pdaf, f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, outflag) + + END SUBROUTINE c__PDAF_put_state_lestkf + + SUBROUTINE c__PDAF_put_state_lenkf(u_collect_state, u_init_dim_obs, & + u_obs_op, u_init_obs, u_prepoststep, u_localize, u_add_obs_err, & + u_init_obs_covar, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Apply localization to HP and HPH^T + procedure(c__localize_covar_pdaf) :: u_localize + ! Add obs error covariance R to HPH in EnKF + procedure(c__add_obs_err_pdaf) :: u_add_obs_err + ! Initialize obs. error cov. matrix R in EnKF + procedure(c__init_obs_covar_pdaf) :: u_init_obs_covar + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + localize_covar_pdaf_c_ptr => u_localize + add_obs_err_pdaf_c_ptr => u_add_obs_err + init_obs_covar_pdaf_c_ptr => u_init_obs_covar + + call PDAF_put_state_lenkf(f__collect_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__prepoststep_pdaf, f__localize_covar_pdaf, f__add_obs_err_pdaf, & + f__init_obs_covar_pdaf, outflag) + + END SUBROUTINE c__PDAF_put_state_lenkf + + SUBROUTINE c__PDAF_put_state_lseik(u_collect_state, u_init_dim_obs, & + u_obs_op, u_init_obs, u_init_obs_l, u_prepoststep, u_prodrinva_l, & + u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, u_g2l_state, & + u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + + call PDAF_put_state_lseik(f__collect_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__init_obs_l_pdaf, f__prepoststep_pdaf, f__prodrinva_l_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, & + f__l2g_state_pdaf, f__g2l_obs_pdaf, f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, outflag) + + END SUBROUTINE c__PDAF_put_state_lseik + + SUBROUTINE c__PDAF_put_state_en3dvar_lestkf(u_collect_state, u_init_dim_obs, & + u_obs_op, u_init_obs, u_prodrinva, u_cvt_ens, u_cvt_adj_ens, & + u_obs_op_lin, u_obs_op_adj, u_init_dim_obs_f, u_obs_op_f, u_init_obs_f, & + u_init_obs_l, u_prodrinva_l, u_init_n_domains_p, u_init_dim_l, & + u_init_dim_obs_l, u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, & + u_init_obsvar_l, u_prepoststep, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble var) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs_f + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_f + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs_f + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + init_dim_obs_f_pdaf_c_ptr => u_init_dim_obs_f + obs_op_f_pdaf_c_ptr => u_obs_op_f + init_obs_f_pdaf_c_ptr => u_init_obs_f + init_obs_l_pdaf_c_ptr => u_init_obs_l + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAF_put_state_en3dvar_lestkf(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__init_obs_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, & + f__init_obs_f_pdaf, f__init_obs_l_pdaf, f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, f__l2g_state_pdaf, f__g2l_obs_pdaf, & + f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF_put_state_en3dvar_lestkf + + SUBROUTINE c__PDAF_put_state_lknetf(u_collect_state, u_init_dim_obs, & + u_obs_op, u_init_obs, u_init_obs_l, u_prepoststep, u_prodrinva_l, & + u_prodrinva_hyb_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_state, u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + u_likelihood_l, u_likelihood_hyb_l, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide product R^-1 A on local analysis domain with hybrid weight + procedure(c__prodrinva_hyb_l_pdaf) :: u_prodrinva_hyb_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! Compute likelihood + procedure(c__likelihood_l_pdaf) :: u_likelihood_l + ! Compute likelihood with hybrid weight + procedure(c__likelihood_hyb_l_pdaf) :: u_likelihood_hyb_l + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + prodrinva_hyb_l_pdaf_c_ptr => u_prodrinva_hyb_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + likelihood_l_pdaf_c_ptr => u_likelihood_l + likelihood_hyb_l_pdaf_c_ptr => u_likelihood_hyb_l + + call PDAF_put_state_lknetf(f__collect_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__init_obs_l_pdaf, f__prepoststep_pdaf, f__prodrinva_l_pdaf, & + f__prodrinva_hyb_l_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__g2l_state_pdaf, f__l2g_state_pdaf, f__g2l_obs_pdaf, f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, & + f__likelihood_l_pdaf, f__likelihood_hyb_l_pdaf, outflag) + + END SUBROUTINE c__PDAF_put_state_lknetf + + SUBROUTINE c__PDAF_put_state_hyb3dvar_estkf(u_collect_state, u_init_dim_obs, & + u_obs_op, u_init_obs, u_prodrinva, u_cvt, u_cvt_adj, u_cvt_ens, & + u_cvt_adj_ens, u_obs_op_lin, u_obs_op_adj, u_init_obsvar, u_prepoststep, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Apply control vector transform matrix (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble var) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + init_obsvar_pdaf_c_ptr => u_init_obsvar + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAF_put_state_hyb3dvar_estkf(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__init_obs_pdaf, f__prodrinva_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__init_obsvar_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF_put_state_hyb3dvar_estkf + + SUBROUTINE c__PDAF_put_state_lnetf(u_collect_state, u_init_dim_obs, & + u_obs_op, u_init_obs, u_init_obs_l, u_prepoststep, u_likelihood_l, & + u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, u_g2l_state, & + u_l2g_state, u_g2l_obs, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Compute observation likelihood for an ensemble member + procedure(c__likelihood_l_pdaf) :: u_likelihood_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + likelihood_l_pdaf_c_ptr => u_likelihood_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + + call PDAF_put_state_lnetf(f__collect_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__init_obs_l_pdaf, f__prepoststep_pdaf, f__likelihood_l_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, & + f__l2g_state_pdaf, f__g2l_obs_pdaf, outflag) + + END SUBROUTINE c__PDAF_put_state_lnetf + + SUBROUTINE c__PDAF_put_state_letkf(u_collect_state, u_init_dim_obs, & + u_obs_op, u_init_obs, u_init_obs_l, u_prepoststep, u_prodrinva_l, & + u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, u_g2l_state, & + u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + + call PDAF_put_state_letkf(f__collect_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__init_obs_l_pdaf, f__prepoststep_pdaf, f__prodrinva_l_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, & + f__l2g_state_pdaf, f__g2l_obs_pdaf, f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, outflag) + + END SUBROUTINE c__PDAF_put_state_letkf + + SUBROUTINE c__PDAF_put_state_en3dvar_estkf(u_collect_state, u_init_dim_obs, & + u_obs_op, u_init_obs, u_prodrinva, u_cvt_ens, u_cvt_adj_ens, & + u_obs_op_lin, u_obs_op_adj, u_init_obsvar, u_prepoststep, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble var) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + init_obsvar_pdaf_c_ptr => u_init_obsvar + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAF_put_state_en3dvar_estkf(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__init_obs_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__init_obsvar_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF_put_state_en3dvar_estkf + + SUBROUTINE c__PDAF_put_state_hyb3dvar_lestkf(u_collect_state, & + u_init_dim_obs, u_obs_op, u_init_obs, u_prodrinva, u_cvt_ens, & + u_cvt_adj_ens, u_cvt, u_cvt_adj, u_obs_op_lin, u_obs_op_adj, & + u_init_dim_obs_f, u_obs_op_f, u_init_obs_f, u_init_obs_l, u_prodrinva_l, & + u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, u_g2l_state, & + u_l2g_state, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, u_prepoststep, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble var) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs_f + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_f + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs_f + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: u_g2l_state + ! Init full state from state on local analysis domain + procedure(c__l2g_state_pdaf) :: u_l2g_state + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + init_dim_obs_f_pdaf_c_ptr => u_init_dim_obs_f + obs_op_f_pdaf_c_ptr => u_obs_op_f + init_obs_f_pdaf_c_ptr => u_init_obs_f + init_obs_l_pdaf_c_ptr => u_init_obs_l + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_state_pdaf_c_ptr => u_g2l_state + l2g_state_pdaf_c_ptr => u_l2g_state + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAF_put_state_hyb3dvar_lestkf(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__init_obs_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__cvt_pdaf, & + f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, & + f__init_obs_f_pdaf, f__init_obs_l_pdaf, f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, f__l2g_state_pdaf, f__g2l_obs_pdaf, & + f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF_put_state_hyb3dvar_lestkf + + SUBROUTINE c__PDAF_put_state_netf(u_collect_state, u_init_dim_obs, u_obs_op, & + u_init_obs, u_prepoststep, u_likelihood, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Init. observation vector on local analysis domain + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Compute observation likelihood for an ensemble member + procedure(c__likelihood_pdaf) :: u_likelihood + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + likelihood_pdaf_c_ptr => u_likelihood + + call PDAF_put_state_netf(f__collect_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__prepoststep_pdaf, f__likelihood_pdaf, outflag) + + END SUBROUTINE c__PDAF_put_state_netf + + SUBROUTINE c__PDAF_put_state_etkf(u_collect_state, u_init_dim_obs, u_obs_op, & + u_init_obs, u_prepoststep, u_prodrinva, u_init_obsvar, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_pdaf_c_ptr => u_prodrinva + init_obsvar_pdaf_c_ptr => u_init_obsvar + + call PDAF_put_state_etkf(f__collect_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__prepoststep_pdaf, f__prodrinva_pdaf, f__init_obsvar_pdaf, outflag) + + END SUBROUTINE c__PDAF_put_state_etkf + + SUBROUTINE c__PDAF_put_state_ensrf(u_collect_state, u_init_dim_obs, & + u_obs_op, u_init_obs, u_init_obsvars, u_localize_covar_serial, & + u_prepoststep, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Initialize vector of observation error variances + procedure(c__init_obsvars_pdaf) :: u_init_obsvars + ! Apply localization for single-observation vectors + procedure(c__localize_covar_serial_pdaf) :: u_localize_covar_serial + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obsvars_pdaf_c_ptr => u_init_obsvars + localize_covar_serial_pdaf_c_ptr => u_localize_covar_serial + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAF_put_state_ensrf(f__collect_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__init_obsvars_pdaf, f__localize_covar_serial_pdaf, f__prepoststep_pdaf, & + outflag) + + END SUBROUTINE c__PDAF_put_state_ensrf + + SUBROUTINE c__PDAF_put_state_enkf(u_collect_state, u_init_dim_obs, u_obs_op, & + u_init_obs, u_prepoststep, u_add_obs_err, u_init_obs_covar, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Add obs error covariance R to HPH in EnKF + procedure(c__add_obs_err_pdaf) :: u_add_obs_err + ! Initialize obs. error cov. matrix R in EnKF + procedure(c__init_obs_covar_pdaf) :: u_init_obs_covar + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + add_obs_err_pdaf_c_ptr => u_add_obs_err + init_obs_covar_pdaf_c_ptr => u_init_obs_covar + + call PDAF_put_state_enkf(f__collect_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__prepoststep_pdaf, f__add_obs_err_pdaf, f__init_obs_covar_pdaf, outflag) + + END SUBROUTINE c__PDAF_put_state_enkf + + SUBROUTINE c__PDAF_put_state_seik(u_collect_state, u_init_dim_obs, u_obs_op, & + u_init_obs, u_prepoststep, u_prodrinva, u_init_obsvar, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_pdaf_c_ptr => u_prodrinva + init_obsvar_pdaf_c_ptr => u_init_obsvar + + call PDAF_put_state_seik(f__collect_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__prepoststep_pdaf, f__prodrinva_pdaf, f__init_obsvar_pdaf, outflag) + + END SUBROUTINE c__PDAF_put_state_seik + + SUBROUTINE c__PDAF_put_state_generate_obs(u_collect_state, u_init_dim_obs_f, & + u_obs_op_f, u_init_obserr_f, u_get_obs_f, u_prepoststep, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs_f + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_f + ! Initialize vector of observation error standard deviations + procedure(c__init_obserr_f_pdaf) :: u_init_obserr_f + ! Provide observation vector + procedure(c__get_obs_f_pdaf) :: u_get_obs_f + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_f_pdaf_c_ptr => u_init_dim_obs_f + obs_op_f_pdaf_c_ptr => u_obs_op_f + init_obserr_f_pdaf_c_ptr => u_init_obserr_f + get_obs_f_pdaf_c_ptr => u_get_obs_f + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAF_put_state_generate_obs(f__collect_state_pdaf, f__init_dim_obs_f_pdaf, & + f__obs_op_f_pdaf, f__init_obserr_f_pdaf, f__get_obs_f_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF_put_state_generate_obs + + SUBROUTINE c__PDAF_put_state_pf(u_collect_state, u_init_dim_obs, u_obs_op, & + u_init_obs, u_prepoststep, u_likelihood, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Init. observation vector on local analysis domain + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Compute observation likelihood for an ensemble member + procedure(c__likelihood_pdaf) :: u_likelihood + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + likelihood_pdaf_c_ptr => u_likelihood + + call PDAF_put_state_pf(f__collect_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__prepoststep_pdaf, f__likelihood_pdaf, outflag) + + END SUBROUTINE c__PDAF_put_state_pf + + SUBROUTINE c__PDAF_put_state_3dvar(u_collect_state, u_init_dim_obs, & + u_obs_op, u_init_obs, u_prodrinva, u_cvt, u_cvt_adj, u_obs_op_lin, & + u_obs_op_adj, u_prepoststep, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAF_put_state_3dvar(f__collect_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__prodrinva_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF_put_state_3dvar + + SUBROUTINE c__PDAF_put_state_estkf(u_collect_state, u_init_dim_obs, & + u_obs_op, u_init_obs, u_prepoststep, u_prodrinva, u_init_obsvar, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_pdaf_c_ptr => u_prodrinva + init_obsvar_pdaf_c_ptr => u_init_obsvar + + call PDAF_put_state_estkf(f__collect_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__prepoststep_pdaf, f__prodrinva_pdaf, f__init_obsvar_pdaf, outflag) + + END SUBROUTINE c__PDAF_put_state_estkf + + SUBROUTINE c__PDAF_put_state_prepost(u_collect_state, u_prepoststep, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + collect_state_pdaf_c_ptr => u_collect_state + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAF_put_state_prepost(f__collect_state_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAF_put_state_prepost +END MODULE pdaf_c_put diff --git a/pyPDAF/source/src/fortran/pdaf_c_setter.f90 b/pyPDAF/source/src/fortran/pdaf_c_setter.f90 new file mode 100644 index 0000000000000000000000000000000000000000..821920b78da4d589a9c6af2e73673fd5ae78c337 --- /dev/null +++ b/pyPDAF/source/src/fortran/pdaf_c_setter.f90 @@ -0,0 +1,100 @@ +MODULE pdaf_c_setter +use iso_c_binding, only: c_int, c_double, c_bool +use PDAF +use pdaf_c_cb_interface +implicit none + +contains + SUBROUTINE c__PDAF_set_comm_pdaf(in_comm_pdaf) bind(c) + ! MPI communicator for PDAF + INTEGER(c_int), INTENT(in) :: in_comm_pdaf + + + call PDAF_set_comm_pdaf(in_comm_pdaf) + + END SUBROUTINE c__PDAF_set_comm_pdaf + + SUBROUTINE c__PDAF_set_debug_flag(debugval) bind(c) + ! Value for debugging flag + INTEGER(c_int), INTENT(in) :: debugval + + + call PDAF_set_debug_flag(debugval) + + END SUBROUTINE c__PDAF_set_debug_flag + + SUBROUTINE c__PDAF_set_ens_pointer(ens_ptr, status) bind(c) + ! Pointer to ensemble array + REAL(c_double), POINTER, DIMENSION(:,:), INTENT(out) :: ens_ptr + ! Status flag + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_set_ens_pointer(ens_ptr, status) + END SUBROUTINE c__PDAF_set_ens_pointer + + SUBROUTINE c__PDAF_set_iparam(id, value, flag) bind(c) + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + INTEGER(c_int), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(inout) :: flag + + + call PDAF_set_iparam(id, value, flag) + + END SUBROUTINE c__PDAF_set_iparam + + SUBROUTINE c__PDAF_set_memberid(memberid) bind(c) + ! Index in the local ensemble + INTEGER(c_int), INTENT(inout) :: memberid + + + call PDAF_set_memberid(memberid) + + END SUBROUTINE c__PDAF_set_memberid + + SUBROUTINE c__PDAF_set_offline_mode(screen) bind(c) + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + + call PDAF_set_offline_mode(screen) + + END SUBROUTINE c__PDAF_set_offline_mode + + SUBROUTINE c__PDAF_set_rparam(id, value, flag) bind(c) + ! Index of parameter + INTEGER(c_int), INTENT(in) :: id + ! Parameter value + REAL(c_double), INTENT(in) :: value + ! Status flag: 0 for no error + INTEGER(c_int), INTENT(inout) :: flag + + + call PDAF_set_rparam(id, value, flag) + + END SUBROUTINE c__PDAF_set_rparam + + SUBROUTINE c__PDAF_set_seedset(seedset_in) bind(c) + ! Seedset index (1-20) + INTEGER(c_int), INTENT(in) :: seedset_in + + + call PDAF_set_seedset(seedset_in) + + END SUBROUTINE c__PDAF_set_seedset + + SUBROUTINE c__PDAF_set_smootherens(sens_point, maxlag, status) bind(c) + ! Pointer to smoother array + REAL(c_double), POINTER, DIMENSION(:,:,:), INTENT(out) :: sens_point + ! Number of past timesteps in sens + INTEGER(c_int), INTENT(in) :: maxlag + ! Status flag, + INTEGER(c_int), INTENT(out) :: status + + + call PDAF_set_smootherens(sens_point, maxlag, status) + END SUBROUTINE c__PDAF_set_smootherens +END MODULE pdaf_c_setter diff --git a/pyPDAF/source/src/fortran/pdaflocal_c.f90 b/pyPDAF/source/src/fortran/pdaflocal_c.f90 new file mode 100644 index 0000000000000000000000000000000000000000..2aa749ef6e8a8ca68172b3f3f3b2a9798ba523b8 --- /dev/null +++ b/pyPDAF/source/src/fortran/pdaflocal_c.f90 @@ -0,0 +1,35 @@ +MODULE pdaflocal_c +use iso_c_binding, only: c_int, c_double, c_bool +use PDAF +use pdaf_c_cb_interface + +implicit none + +contains + SUBROUTINE c__PDAFlocal_set_indices(dim_l, map) bind(c) + ! Dimension of local state vector + INTEGER(c_int), INTENT(in) :: dim_l + ! Index array for mapping between local and global state vector + INTEGER(c_int), DIMENSION(dim_l), INTENT(in) :: map + + + call PDAFlocal_set_indices(dim_l, map) + + END SUBROUTINE c__PDAFlocal_set_indices + + SUBROUTINE c__PDAFlocal_set_increment_weights(dim_l, weights) bind(c) + ! Dimension of local state vector + INTEGER(c_int), INTENT(in) :: dim_l + ! Weights array + REAL(c_double), DIMENSION(dim_l), INTENT(in) :: weights + + + call PDAFlocal_set_increment_weights(dim_l, weights) + + END SUBROUTINE c__PDAFlocal_set_increment_weights + + SUBROUTINE c__PDAFlocal_clear_increment_weights() bind(c) + call PDAFlocal_clear_increment_weights() + + END SUBROUTINE c__PDAFlocal_clear_increment_weights +END MODULE pdaflocal_c diff --git a/pyPDAF/source/src/fortran/pdaflocal_c_assim.f90 b/pyPDAF/source/src/fortran/pdaflocal_c_assim.f90 new file mode 100644 index 0000000000000000000000000000000000000000..a94df5ed973679e78a28bdf5233449fc81f761fd --- /dev/null +++ b/pyPDAF/source/src/fortran/pdaflocal_c_assim.f90 @@ -0,0 +1,511 @@ +MODULE pdaflocal_c_assim +use iso_c_binding, only: c_double, c_int, c_bool +use PDAF +use pdaf_c_cb_interface +use pdaf_c_f_interface + +implicit none + +contains + SUBROUTINE c__PDAFlocal_assimilate_en3dvar_lestkf(u_collect_state, & + u_distribute_state, u_init_dim_obs, u_obs_op, u_init_obs, u_prodrinva, & + u_cvt_ens, u_cvt_adj_ens, u_obs_op_lin, u_obs_op_adj, u_init_dim_obs_f, & + u_obs_op_f, u_init_obs_f, u_init_obs_l, u_prodrinva_l, & + u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, u_g2l_obs, & + u_init_obsvar, u_init_obsvar_l, u_prepoststep, u_next_observation, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble var) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs_f + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_f + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs_f + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + init_dim_obs_f_pdaf_c_ptr => u_init_dim_obs_f + obs_op_f_pdaf_c_ptr => u_obs_op_f + init_obs_f_pdaf_c_ptr => u_init_obs_f + init_obs_l_pdaf_c_ptr => u_init_obs_l + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + prepoststep_pdaf_c_ptr => u_prepoststep + next_observation_pdaf_c_ptr => u_next_observation + + call PDAFlocal_assimilate_en3dvar_lestkf(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__prodrinva_pdaf, & + f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, f__init_obs_f_pdaf, f__init_obs_l_pdaf, & + f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__g2l_obs_pdaf, f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFlocal_assimilate_en3dvar_lestkf + + SUBROUTINE c__PDAFlocal_assimilate_hyb3dvar_lestkf(u_collect_state, & + u_distribute_state, u_init_dim_obs, u_obs_op, u_init_obs, u_prodrinva, & + u_cvt_ens, u_cvt_adj_ens, u_cvt, u_cvt_adj, u_obs_op_lin, u_obs_op_adj, & + u_init_dim_obs_f, u_obs_op_f, u_init_obs_f, u_init_obs_l, u_prodrinva_l, & + u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, u_g2l_obs, & + u_init_obsvar, u_init_obsvar_l, u_prepoststep, u_next_observation, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble var) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs_f + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_f + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs_f + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + init_dim_obs_f_pdaf_c_ptr => u_init_dim_obs_f + obs_op_f_pdaf_c_ptr => u_obs_op_f + init_obs_f_pdaf_c_ptr => u_init_obs_f + init_obs_l_pdaf_c_ptr => u_init_obs_l + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + prepoststep_pdaf_c_ptr => u_prepoststep + next_observation_pdaf_c_ptr => u_next_observation + + call PDAFlocal_assimilate_hyb3dvar_lestkf(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__prodrinva_pdaf, & + f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, f__init_obs_f_pdaf, & + f__init_obs_l_pdaf, f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__g2l_obs_pdaf, f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, & + f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFlocal_assimilate_hyb3dvar_lestkf + + SUBROUTINE c__PDAFlocal_assimilate_lseik(u_collect_state, & + u_distribute_state, u_init_dim_obs, u_obs_op, u_init_obs, u_init_obs_l, & + u_prepoststep, u_prodrinva_l, u_init_n_domains_p, u_init_dim_l, & + u_init_dim_obs_l, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + next_observation_pdaf_c_ptr => u_next_observation + + call PDAFlocal_assimilate_lseik(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__init_obs_l_pdaf, f__prepoststep_pdaf, & + f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__g2l_obs_pdaf, f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFlocal_assimilate_lseik + + SUBROUTINE c__PDAFlocal_assimilate_letkf(u_collect_state, & + u_distribute_state, u_init_dim_obs, u_obs_op, u_init_obs, u_init_obs_l, & + u_prepoststep, u_prodrinva_l, u_init_n_domains_p, u_init_dim_l, & + u_init_dim_obs_l, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + next_observation_pdaf_c_ptr => u_next_observation + + call PDAFlocal_assimilate_letkf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__init_obs_l_pdaf, f__prepoststep_pdaf, & + f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__g2l_obs_pdaf, f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFlocal_assimilate_letkf + + SUBROUTINE c__PDAFlocal_assimilate_lestkf(u_collect_state, & + u_distribute_state, u_init_dim_obs, u_obs_op, u_init_obs, u_init_obs_l, & + u_prepoststep, u_prodrinva_l, u_init_n_domains_p, u_init_dim_l, & + u_init_dim_obs_l, u_g2l_obs, u_init_obsvar, u_init_obsvar_l, & + u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + next_observation_pdaf_c_ptr => u_next_observation + + call PDAFlocal_assimilate_lestkf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__init_obs_l_pdaf, f__prepoststep_pdaf, & + f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__g2l_obs_pdaf, f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFlocal_assimilate_lestkf + + SUBROUTINE c__PDAFlocal_assimilate_lnetf(u_collect_state, & + u_distribute_state, u_init_dim_obs, u_obs_op, u_init_obs, u_init_obs_l, & + u_prepoststep, u_likelihood_l, u_init_n_domains_p, u_init_dim_l, & + u_init_dim_obs_l, u_g2l_obs, u_next_observation, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Compute observation likelihood for an ensemble member + procedure(c__likelihood_l_pdaf) :: u_likelihood_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + likelihood_l_pdaf_c_ptr => u_likelihood_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_obs_pdaf_c_ptr => u_g2l_obs + next_observation_pdaf_c_ptr => u_next_observation + + call PDAFlocal_assimilate_lnetf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__init_obs_l_pdaf, f__prepoststep_pdaf, & + f__likelihood_l_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__g2l_obs_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFlocal_assimilate_lnetf + + SUBROUTINE c__PDAFlocal_assimilate_lknetf(u_collect_state, & + u_distribute_state, u_init_dim_obs, u_obs_op, u_init_obs, u_init_obs_l, & + u_prepoststep, u_prodrinva_l, u_prodrinva_hyb_l, u_init_n_domains_p, & + u_init_dim_l, u_init_dim_obs_l, u_g2l_obs, u_init_obsvar, & + u_init_obsvar_l, u_likelihood_l, u_likelihood_hyb_l, u_next_observation, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: u_distribute_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide product R^-1 A on local analysis domain with hybrid weight + procedure(c__prodrinva_hyb_l_pdaf) :: u_prodrinva_hyb_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! Compute likelihood + procedure(c__likelihood_l_pdaf) :: u_likelihood_l + ! Compute likelihood with hybrid weight + procedure(c__likelihood_hyb_l_pdaf) :: u_likelihood_hyb_l + ! Routine to provide time step, time and dimensionof next observation + procedure(c__next_observation_pdaf) :: u_next_observation + + collect_state_pdaf_c_ptr => u_collect_state + distribute_state_pdaf_c_ptr => u_distribute_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + prodrinva_hyb_l_pdaf_c_ptr => u_prodrinva_hyb_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + likelihood_l_pdaf_c_ptr => u_likelihood_l + likelihood_hyb_l_pdaf_c_ptr => u_likelihood_hyb_l + next_observation_pdaf_c_ptr => u_next_observation + + call PDAFlocal_assimilate_lknetf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__init_obs_pdaf, f__init_obs_l_pdaf, f__prepoststep_pdaf, & + f__prodrinva_l_pdaf, f__prodrinva_hyb_l_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__g2l_obs_pdaf, f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, & + f__likelihood_l_pdaf, f__likelihood_hyb_l_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFlocal_assimilate_lknetf +END MODULE pdaflocal_c_assim diff --git a/pyPDAF/source/src/fortran/pdaflocal_c_put.f90 b/pyPDAF/source/src/fortran/pdaflocal_c_put.f90 new file mode 100644 index 0000000000000000000000000000000000000000..a25d843c15a4b8232fc31e389b8d7bd5af045f66 --- /dev/null +++ b/pyPDAF/source/src/fortran/pdaflocal_c_put.f90 @@ -0,0 +1,460 @@ +MODULE pdaflocal_c_put +use iso_c_binding, only: c_double, c_int, c_bool +use PDAF +use pdaf_c_cb_interface +use pdaf_c_f_interface + +implicit none + +contains + SUBROUTINE c__PDAFlocal_put_state_en3dvar_lestkf(u_collect_state, & + u_init_dim_obs, u_obs_op, u_init_obs, u_prodrinva, u_cvt_ens, & + u_cvt_adj_ens, u_obs_op_lin, u_obs_op_adj, u_init_dim_obs_f, u_obs_op_f, & + u_init_obs_f, u_init_obs_l, u_prodrinva_l, u_init_n_domains_p, & + u_init_dim_l, u_init_dim_obs_l, u_g2l_obs, u_init_obsvar, & + u_init_obsvar_l, u_prepoststep, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble var) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs_f + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_f + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs_f + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + init_dim_obs_f_pdaf_c_ptr => u_init_dim_obs_f + obs_op_f_pdaf_c_ptr => u_obs_op_f + init_obs_f_pdaf_c_ptr => u_init_obs_f + init_obs_l_pdaf_c_ptr => u_init_obs_l + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAFlocal_put_state_en3dvar_lestkf(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__init_obs_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, & + f__init_obs_f_pdaf, f__init_obs_l_pdaf, f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_obs_pdaf, f__init_obsvar_pdaf, & + f__init_obsvar_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFlocal_put_state_en3dvar_lestkf + + SUBROUTINE c__PDAFlocal_put_state_hyb3dvar_lestkf(u_collect_state, & + u_init_dim_obs, u_obs_op, u_init_obs, u_prodrinva, u_cvt_ens, & + u_cvt_adj_ens, u_cvt, u_cvt_adj, u_obs_op_lin, u_obs_op_adj, & + u_init_dim_obs_f, u_obs_op_f, u_init_obs_f, u_init_obs_l, u_prodrinva_l, & + u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, u_g2l_obs, & + u_init_obsvar, u_init_obsvar_l, u_prepoststep, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: u_prodrinva + ! Apply control vector transform matrix (ensemble) + procedure(c__cvt_ens_pdaf) :: u_cvt_ens + ! Apply adjoint control vector transform matrix (ensemble var) + procedure(c__cvt_adj_ens_pdaf) :: u_cvt_adj_ens + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: u_cvt + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: u_cvt_adj + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_lin + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: u_obs_op_adj + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs_f + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op_f + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs_f + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + prodrinva_pdaf_c_ptr => u_prodrinva + cvt_ens_pdaf_c_ptr => u_cvt_ens + cvt_adj_ens_pdaf_c_ptr => u_cvt_adj_ens + cvt_pdaf_c_ptr => u_cvt + cvt_adj_pdaf_c_ptr => u_cvt_adj + obs_op_lin_pdaf_c_ptr => u_obs_op_lin + obs_op_adj_pdaf_c_ptr => u_obs_op_adj + init_dim_obs_f_pdaf_c_ptr => u_init_dim_obs_f + obs_op_f_pdaf_c_ptr => u_obs_op_f + init_obs_f_pdaf_c_ptr => u_init_obs_f + init_obs_l_pdaf_c_ptr => u_init_obs_l + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + prepoststep_pdaf_c_ptr => u_prepoststep + + call PDAFlocal_put_state_hyb3dvar_lestkf(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__init_obs_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__cvt_pdaf, & + f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, & + f__init_obs_f_pdaf, f__init_obs_l_pdaf, f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_obs_pdaf, f__init_obsvar_pdaf, & + f__init_obsvar_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFlocal_put_state_hyb3dvar_lestkf + + SUBROUTINE c__PDAFlocal_put_state_lseik(u_collect_state, u_init_dim_obs, & + u_obs_op, u_init_obs, u_init_obs_l, u_prepoststep, u_prodrinva_l, & + u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, u_g2l_obs, & + u_init_obsvar, u_init_obsvar_l, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + + call PDAFlocal_put_state_lseik(f__collect_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__init_obs_l_pdaf, f__prepoststep_pdaf, f__prodrinva_l_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_obs_pdaf, & + f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, outflag) + + END SUBROUTINE c__PDAFlocal_put_state_lseik + + SUBROUTINE c__PDAFlocal_put_state_letkf(u_collect_state, u_init_dim_obs, & + u_obs_op, u_init_obs, u_init_obs_l, u_prepoststep, u_prodrinva_l, & + u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, u_g2l_obs, & + u_init_obsvar, u_init_obsvar_l, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + + call PDAFlocal_put_state_letkf(f__collect_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__init_obs_l_pdaf, f__prepoststep_pdaf, f__prodrinva_l_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_obs_pdaf, & + f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, outflag) + + END SUBROUTINE c__PDAFlocal_put_state_letkf + + SUBROUTINE c__PDAFlocal_put_state_lestkf(u_collect_state, u_init_dim_obs, & + u_obs_op, u_init_obs, u_init_obs_l, u_prepoststep, u_prodrinva_l, & + u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, u_g2l_obs, & + u_init_obsvar, u_init_obsvar_l, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + + call PDAFlocal_put_state_lestkf(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__init_obs_pdaf, f__init_obs_l_pdaf, f__prepoststep_pdaf, f__prodrinva_l_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_obs_pdaf, & + f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, outflag) + + END SUBROUTINE c__PDAFlocal_put_state_lestkf + + SUBROUTINE c__PDAFlocal_put_state_lnetf(u_collect_state, u_init_dim_obs, & + u_obs_op, u_init_obs, u_init_obs_l, u_prepoststep, u_likelihood_l, & + u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, u_g2l_obs, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Compute observation likelihood for an ensemble member + procedure(c__likelihood_l_pdaf) :: u_likelihood_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + likelihood_l_pdaf_c_ptr => u_likelihood_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_obs_pdaf_c_ptr => u_g2l_obs + + call PDAFlocal_put_state_lnetf(f__collect_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__init_obs_pdaf, f__init_obs_l_pdaf, f__prepoststep_pdaf, f__likelihood_l_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_obs_pdaf, outflag) + + END SUBROUTINE c__PDAFlocal_put_state_lnetf + + SUBROUTINE c__PDAFlocal_put_state_lknetf(u_collect_state, u_init_dim_obs, & + u_obs_op, u_init_obs, u_init_obs_l, u_prepoststep, u_prodrinva_l, & + u_prodrinva_hyb_l, u_init_n_domains_p, u_init_dim_l, u_init_dim_obs_l, & + u_g2l_obs, u_init_obsvar, u_init_obsvar_l, u_likelihood_l, & + u_likelihood_hyb_l, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: u_collect_state + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: u_init_dim_obs + ! Observation operator + procedure(c__obs_op_pdaf) :: u_obs_op + ! Initialize PE-local observation vector + procedure(c__init_obs_pdaf) :: u_init_obs + ! Init. observation vector on local analysis domain + procedure(c__init_obs_l_pdaf) :: u_init_obs_l + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: u_prepoststep + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: u_prodrinva_l + ! Provide product R^-1 A on local analysis domain with hybrid weight + procedure(c__prodrinva_hyb_l_pdaf) :: u_prodrinva_hyb_l + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: u_init_n_domains_p + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: u_init_dim_l + ! Initialize dim. of obs. vector for local ana. domain + procedure(c__init_dim_obs_l_pdaf) :: u_init_dim_obs_l + ! Restrict full obs. vector to local analysis domain + procedure(c__g2l_obs_pdaf) :: u_g2l_obs + ! Initialize mean observation error variance + procedure(c__init_obsvar_pdaf) :: u_init_obsvar + ! Initialize local mean observation error variance + procedure(c__init_obsvar_l_pdaf) :: u_init_obsvar_l + ! Compute likelihood + procedure(c__likelihood_l_pdaf) :: u_likelihood_l + ! Compute likelihood with hybrid weight + procedure(c__likelihood_hyb_l_pdaf) :: u_likelihood_hyb_l + + collect_state_pdaf_c_ptr => u_collect_state + init_dim_obs_pdaf_c_ptr => u_init_dim_obs + obs_op_pdaf_c_ptr => u_obs_op + init_obs_pdaf_c_ptr => u_init_obs + init_obs_l_pdaf_c_ptr => u_init_obs_l + prepoststep_pdaf_c_ptr => u_prepoststep + prodrinva_l_pdaf_c_ptr => u_prodrinva_l + prodrinva_hyb_l_pdaf_c_ptr => u_prodrinva_hyb_l + init_n_domains_p_pdaf_c_ptr => u_init_n_domains_p + init_dim_l_pdaf_c_ptr => u_init_dim_l + init_dim_obs_l_pdaf_c_ptr => u_init_dim_obs_l + g2l_obs_pdaf_c_ptr => u_g2l_obs + init_obsvar_pdaf_c_ptr => u_init_obsvar + init_obsvar_l_pdaf_c_ptr => u_init_obsvar_l + likelihood_l_pdaf_c_ptr => u_likelihood_l + likelihood_hyb_l_pdaf_c_ptr => u_likelihood_hyb_l + + call PDAFlocal_put_state_lknetf(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__init_obs_pdaf, f__init_obs_l_pdaf, f__prepoststep_pdaf, f__prodrinva_l_pdaf, & + f__prodrinva_hyb_l_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__g2l_obs_pdaf, f__init_obsvar_pdaf, f__init_obsvar_l_pdaf, f__likelihood_l_pdaf, & + f__likelihood_hyb_l_pdaf, outflag) + + END SUBROUTINE c__PDAFlocal_put_state_lknetf +END MODULE pdaflocal_c_put diff --git a/pyPDAF/source/src/fortran/pdaflocalomi_c_assim.f90 b/pyPDAF/source/src/fortran/pdaflocalomi_c_assim.f90 new file mode 100644 index 0000000000000000000000000000000000000000..a16cba21e44664714c4bcce09784ea598cf7f487 --- /dev/null +++ b/pyPDAF/source/src/fortran/pdaflocalomi_c_assim.f90 @@ -0,0 +1,467 @@ + +MODULE pdaflocalomi_c_assim +use iso_c_binding, only: c_double, c_int, c_bool +use PDAF +use pdaf_c_cb_interface +use pdaf_c_f_interface + +implicit none + +contains + SUBROUTINE c__PDAFlocalomi_assimilate(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_f_pdaf, obs_op_f_pdaf, & + prepoststep_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_f_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_f_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_f_pdaf_c_ptr => init_dim_obs_f_pdaf + obs_op_f_pdaf_c_ptr => obs_op_f_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFlocalomi_assimilate(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, f__prepoststep_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFlocalomi_assimilate + + SUBROUTINE c__PDAFlocalomi_assimilate_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdafomi, obs_op_pdafomi, & + prepoststep_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdafomi, prodrinva_l_pdafomi, next_observation_pdaf, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdafomi + ! Provide product of inverse of R with matrix A + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdafomi + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdafomi + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdafomi + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFlocalomi_assimilate_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__prepoststep_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__prodrinva_l_pdaf, f__next_observation_pdaf, & + outflag) + + END SUBROUTINE c__PDAFlocalomi_assimilate_nondiagR + + SUBROUTINE c__PDAFlocalomi_assimilate_lnetf_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdafomi, obs_op_pdafomi, & + prepoststep_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdafomi, likelihood_l_pdafomi, next_observation_pdaf, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdafomi + ! Compute likelihood and apply localization + procedure(c__likelihood_l_pdaf) :: likelihood_l_pdafomi + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdafomi + likelihood_l_pdaf_c_ptr => likelihood_l_pdafomi + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFlocalomi_assimilate_lnetf_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__prepoststep_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__likelihood_l_pdaf, f__next_observation_pdaf, & + outflag) + + END SUBROUTINE c__PDAFlocalomi_assimilate_lnetf_nondiagR + + SUBROUTINE c__PDAFlocalomi_assimilate_lknetf_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdafomi, obs_op_pdafomi, & + prepoststep_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdafomi, prodrinva_l_pdafomi, prodrinva_hyb_l_pdafomi, & + likelihood_l_pdafomi, likelihood_hyb_l_pdafomi, next_observation_pdaf, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdafomi + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdafomi + ! Product R^-1 A on local analysis domain with hybrid weight + procedure(c__prodrinva_hyb_l_pdaf) :: prodrinva_hyb_l_pdafomi + ! Compute likelihood and apply localization + procedure(c__likelihood_l_pdaf) :: likelihood_l_pdafomi + ! Compute likelihood and apply localization with tempering + procedure(c__likelihood_hyb_l_pdaf) :: likelihood_hyb_l_pdafomi + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdafomi + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdafomi + prodrinva_hyb_l_pdaf_c_ptr => prodrinva_hyb_l_pdafomi + likelihood_l_pdaf_c_ptr => likelihood_l_pdafomi + likelihood_hyb_l_pdaf_c_ptr => likelihood_hyb_l_pdafomi + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFlocalomi_assimilate_lknetf_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__prepoststep_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__prodrinva_l_pdaf, f__prodrinva_hyb_l_pdaf, & + f__likelihood_l_pdaf, f__likelihood_hyb_l_pdaf, f__next_observation_pdaf, & + outflag) + + END SUBROUTINE c__PDAFlocalomi_assimilate_lknetf_nondiagR + + SUBROUTINE c__PDAFlocalomi_assimilate_en3dvar_lestkf(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_f_pdaf, obs_op_f_pdaf, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, init_n_domains_pdaf, & + init_dim_l_pdaf, init_dim_obs_l_pdaf, prepoststep_pdaf, & + next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_f_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_f_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_f_pdaf_c_ptr => init_dim_obs_f_pdaf + obs_op_f_pdaf_c_ptr => obs_op_f_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFlocalomi_assimilate_en3dvar_lestkf(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, & + f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFlocalomi_assimilate_en3dvar_lestkf + + SUBROUTINE c__PDAFlocalomi_assimilate_hyb3dvar_lestkf(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_f_pdaf, obs_op_f_pdaf, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, & + obs_op_adj_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, prepoststep_pdaf, next_observation_pdaf, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_f_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_f_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_f_pdaf_c_ptr => init_dim_obs_f_pdaf + obs_op_f_pdaf_c_ptr => obs_op_f_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFlocalomi_assimilate_hyb3dvar_lestkf(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, & + f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFlocalomi_assimilate_hyb3dvar_lestkf + + SUBROUTINE c__PDAFlocalomi_assimilate_en3dvar_lestkf_nondiagR( & + collect_state_pdaf, distribute_state_pdaf, init_dim_obs_pdafomi, & + obs_op_pdafomi, prodrinva_pdafomi, cvt_ens_pdaf, cvt_adj_ens_pdaf, & + obs_op_lin_pdafomi, obs_op_adj_pdafomi, prodrinva_l_pdafomi, & + init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdafomi, & + prepoststep_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdafomi + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdafomi + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdafomi + ! Provide product R^-1 A with localization + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdafomi + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prodrinva_pdaf_c_ptr => prodrinva_pdafomi + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdafomi + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdafomi + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdafomi + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFlocalomi_assimilate_en3dvar_lestkf_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__prodrinva_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFlocalomi_assimilate_en3dvar_lestkf_nondiagR + + SUBROUTINE c__PDAFlocalomi_assimilate_hyb3dvar_lestkf_nondiagR( & + collect_state_pdaf, distribute_state_pdaf, init_dim_obs_pdafomi, & + obs_op_pdafomi, prodrinva_pdafomi, cvt_ens_pdaf, cvt_adj_ens_pdaf, & + cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdafomi, obs_op_adj_pdafomi, & + prodrinva_l_pdafomi, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdafomi, prepoststep_pdaf, next_observation_pdaf, & + outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdafomi + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdafomi + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdafomi + ! Provide product R^-1 A + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdafomi + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prodrinva_pdaf_c_ptr => prodrinva_pdafomi + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdafomi + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdafomi + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdafomi + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFlocalomi_assimilate_hyb3dvar_lestkf_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__prodrinva_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__cvt_pdaf, & + f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFlocalomi_assimilate_hyb3dvar_lestkf_nondiagR +END MODULE pdaflocalomi_c_assim diff --git a/pyPDAF/source/src/fortran/pdaflocalomi_c_put.f90 b/pyPDAF/source/src/fortran/pdaflocalomi_c_put.f90 new file mode 100644 index 0000000000000000000000000000000000000000..fd93613a03224b964f93ca09afe08b5534390b3c --- /dev/null +++ b/pyPDAF/source/src/fortran/pdaflocalomi_c_put.f90 @@ -0,0 +1,402 @@ +MODULE pdaflocalomi_c_put +use iso_c_binding, only: c_double, c_int, c_bool +use PDAF +use pdaf_c_cb_interface +use pdaf_c_f_interface + +implicit none + +contains + SUBROUTINE c__PDAFlocalomi_put_state_en3dvar_lestkf(collect_state_pdaf, & + init_dim_obs_f_pdaf, obs_op_f_pdaf, cvt_ens_pdaf, cvt_adj_ens_pdaf, & + obs_op_lin_pdaf, obs_op_adj_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_f_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_f_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_f_pdaf_c_ptr => init_dim_obs_f_pdaf + obs_op_f_pdaf_c_ptr => obs_op_f_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAFlocalomi_put_state_en3dvar_lestkf(f__collect_state_pdaf, & + f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFlocalomi_put_state_en3dvar_lestkf + + SUBROUTINE c__PDAFlocalomi_put_state_hyb3dvar_lestkf(collect_state_pdaf, & + init_dim_obs_f_pdaf, obs_op_f_pdaf, cvt_ens_pdaf, cvt_adj_ens_pdaf, & + cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, & + init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdaf, & + prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_f_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_f_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_f_pdaf_c_ptr => init_dim_obs_f_pdaf + obs_op_f_pdaf_c_ptr => obs_op_f_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAFlocalomi_put_state_hyb3dvar_lestkf(f__collect_state_pdaf, & + f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, & + f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFlocalomi_put_state_hyb3dvar_lestkf + + SUBROUTINE c__PDAFlocalomi_put_state_en3dvar_lestkf_nondiagR( & + collect_state_pdaf, init_dim_obs_pdafomi, obs_op_pdafomi, & + prodrinva_pdafomi, cvt_ens_pdaf, cvt_adj_ens_pdaf, obs_op_lin_pdafomi, & + obs_op_adj_pdafomi, prodrinva_l_pdafomi, init_n_domains_pdaf, & + init_dim_l_pdaf, init_dim_obs_l_pdafomi, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdafomi + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdafomi + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdafomi + ! Provide product R^-1 A + procedure(c__prodRinvA_l_pdaf) :: prodrinva_l_pdafomi + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prodrinva_pdaf_c_ptr => prodrinva_pdafomi + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdafomi + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdafomi + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdafomi + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAFlocalomi_put_state_en3dvar_lestkf_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFlocalomi_put_state_en3dvar_lestkf_nondiagR + + SUBROUTINE c__PDAFlocalomi_put_state_hyb3dvar_lestkf_nondiagR( & + collect_state_pdaf, init_dim_obs_pdafomi, obs_op_pdafomi, & + prodrinva_pdafomi, cvt_ens_pdaf, cvt_adj_ens_pdaf, cvt_pdaf, & + cvt_adj_pdaf, obs_op_lin_pdafomi, obs_op_adj_pdafomi, & + prodrinva_l_pdafomi, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdafomi, prepoststep_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdafomi + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdafomi + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdafomi + ! Provide product R^-1 A + procedure(c__prodRinvA_l_pdaf) :: prodrinva_l_pdafomi + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prodrinva_pdaf_c_ptr => prodrinva_pdafomi + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdafomi + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdafomi + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdafomi + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAFlocalomi_put_state_hyb3dvar_lestkf_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFlocalomi_put_state_hyb3dvar_lestkf_nondiagR + + SUBROUTINE c__PDAFlocalomi_put_state(collect_state_pdaf, & + init_dim_obs_f_pdaf, obs_op_f_pdaf, prepoststep_pdaf, & + init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_f_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_f_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_f_pdaf_c_ptr => init_dim_obs_f_pdaf + obs_op_f_pdaf_c_ptr => obs_op_f_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + + call PDAFlocalomi_put_state(f__collect_state_pdaf, f__init_dim_obs_f_pdaf, & + f__obs_op_f_pdaf, f__prepoststep_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, outflag) + + END SUBROUTINE c__PDAFlocalomi_put_state + + SUBROUTINE c__PDAFlocalomi_put_state_nondiagR(collect_state_pdaf, & + init_dim_obs_pdafomi, obs_op_pdafomi, prepoststep_pdaf, & + init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdafomi, & + prodrinva_l_pdafomi, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdafomi + ! Provide product of inverse of R with matrix A + procedure(c__prodRinvA_l_pdaf) :: prodrinva_l_pdafomi + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdafomi + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdafomi + + call PDAFlocalomi_put_state_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prepoststep_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__prodrinva_l_pdaf, outflag) + + END SUBROUTINE c__PDAFlocalomi_put_state_nondiagR + + SUBROUTINE c__PDAFlocalomi_put_state_lnetf_nondiagR(collect_state_pdaf, & + init_dim_obs_pdafomi, obs_op_pdafomi, prepoststep_pdaf, & + init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdafomi, & + likelihood_l_pdafomi, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdafomi + ! Compute likelihood and apply localization + procedure(c__likelihood_l_pdaf) :: likelihood_l_pdafomi + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdafomi + likelihood_l_pdaf_c_ptr => likelihood_l_pdafomi + + call PDAFlocalomi_put_state_lnetf_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prepoststep_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__likelihood_l_pdaf, outflag) + + END SUBROUTINE c__PDAFlocalomi_put_state_lnetf_nondiagR + + SUBROUTINE c__PDAFlocalomi_put_state_lknetf_nondiagR(collect_state_pdaf, & + init_dim_obs_pdafomi, obs_op_pdafomi, prepoststep_pdaf, & + init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdafomi, & + prodrinva_l_pdafomi, prodrinva_hyb_l_pdafomi, likelihood_l_pdafomi, & + likelihood_hyb_l_pdafomi, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdafomi + ! Provide product R^-1 A on local analysis domain + procedure(c__prodRinvA_l_pdaf) :: prodrinva_l_pdafomi + ! Product R^-1 A on local analysis domain with hybrid weight + procedure(c__prodrinva_hyb_l_pdaf) :: prodrinva_hyb_l_pdafomi + ! Compute likelihood and apply localization + procedure(c__likelihood_l_pdaf) :: likelihood_l_pdafomi + ! Compute likelihood and apply localization with tempering + procedure(c__likelihood_hyb_l_pdaf) :: likelihood_hyb_l_pdafomi + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdafomi + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdafomi + prodrinva_hyb_l_pdaf_c_ptr => prodrinva_hyb_l_pdafomi + likelihood_l_pdaf_c_ptr => likelihood_l_pdafomi + likelihood_hyb_l_pdaf_c_ptr => likelihood_hyb_l_pdafomi + + call PDAFlocalomi_put_state_lknetf_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prepoststep_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__prodrinva_l_pdaf, f__prodrinva_hyb_l_pdaf, f__likelihood_l_pdaf, & + f__likelihood_hyb_l_pdaf, outflag) + + END SUBROUTINE c__PDAFlocalomi_put_state_lknetf_nondiagR +END MODULE pdaflocalomi_c_put diff --git a/pyPDAF/source/src/fortran/pdafomi_c.f90 b/pyPDAF/source/src/fortran/pdafomi_c.f90 new file mode 100644 index 0000000000000000000000000000000000000000..3132657a48077ad61dbebcf2e719b0cf11507b2e --- /dev/null +++ b/pyPDAF/source/src/fortran/pdafomi_c.f90 @@ -0,0 +1,514 @@ +module pdafomi_c +use iso_c_binding, only: c_int, c_double, c_bool +use PDAFomi +implicit none + +type(obs_f), allocatable, target :: thisobs(:) +type(obs_l), allocatable, target :: thisobs_l(:) +integer :: n_obs_omi + +contains + subroutine c__PDAFomi_init(n_obs) bind(c) + ! number of observations + integer(c_int), intent(in) :: n_obs + n_obs_omi = n_obs + if (.not. allocated(thisobs)) allocate(thisobs(n_obs)) + if (.not. allocated(thisobs_l)) allocate(thisobs_l(n_obs)) + end subroutine c__PDAFomi_init + + subroutine c__PDAFomi_init_local() bind(c) + if (.not. allocated(thisobs_l)) allocate(thisobs_l(n_obs_omi)) + end subroutine c__PDAFomi_init_local + + + SUBROUTINE c__PDAFomi_check_error(flag) bind(c) + ! Error flag + INTEGER(c_int), INTENT(inout) :: flag + + call PDAFomi_check_error(flag) + + END SUBROUTINE c__PDAFomi_check_error + + SUBROUTINE c__PDAFomi_gather_obs(i_obs, dim_obs_p, obs_p, ivar_obs_p, ocoord_p, & + ncoord, lradius, dim_obs_f) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Number of process-local observation + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Vector of process-local observations + REAL(c_double), DIMENSION(:), INTENT(in) :: obs_p + ! Vector of process-local inverse observation error variance + REAL(c_double), DIMENSION(:), INTENT(in) :: ivar_obs_p + ! Array of process-local observation coordinates + REAL(c_double), DIMENSION(:,:), INTENT(in) :: ocoord_p + ! Number of rows of coordinate array + INTEGER(c_int), INTENT(in) :: ncoord + ! Localization radius (the maximum radius used in this process domain) + REAL(c_double), INTENT(in) :: lradius + ! Full number of observations + INTEGER(c_int), INTENT(out) :: dim_obs_f + + + call PDAFomi_gather_obs(thisobs(i_obs), dim_obs_p, obs_p, ivar_obs_p, & + ocoord_p, ncoord, lradius, dim_obs_f) + + END SUBROUTINE c__PDAFomi_gather_obs + + SUBROUTINE c__PDAFomi_gather_obsstate(i_obs, obsstate_p, obsstate_f) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Vector of process-local observed state + REAL(c_double), DIMENSION(:), INTENT(in) :: obsstate_p + ! Full observed vector for all types + REAL(c_double), DIMENSION(:), INTENT(inout) :: obsstate_f + + + call PDAFomi_gather_obsstate(thisobs(i_obs), obsstate_p, obsstate_f) + + END SUBROUTINE c__PDAFomi_gather_obsstate + + SUBROUTINE c__PDAFomi_get_interp_coeff_tri(gpc, oc, icoeff) bind(c) + ! Coordinates of grid points; dim(3,2) + REAL(c_double), DIMENSION(:,:), INTENT(in) :: gpc + ! Coordinates of observation; dim(2) + REAL(c_double), DIMENSION(:), INTENT(in) :: oc + ! Interpolation coefficients; dim(3) + REAL(c_double), DIMENSION(:), INTENT(inout) :: icoeff + + + call PDAFomi_get_interp_coeff_tri(gpc, oc, icoeff) + + END SUBROUTINE c__PDAFomi_get_interp_coeff_tri + + SUBROUTINE c__PDAFomi_get_interp_coeff_lin1D(gpc, oc, icoeff) bind(c) + ! Coordinates of grid points (dim=2) + REAL(c_double), DIMENSION(:), INTENT(in) :: gpc + ! Coordinates of observation + REAL(c_double), INTENT(in) :: oc + ! Interpolation coefficients (dim=2) + REAL(c_double), DIMENSION(:), INTENT(inout) :: icoeff + + + call PDAFomi_get_interp_coeff_lin1D(gpc, oc, icoeff) + + END SUBROUTINE c__PDAFomi_get_interp_coeff_lin1D + + SUBROUTINE c__PDAFomi_get_interp_coeff_lin(num_gp, n_dim, gpc, oc, & + icoeff) bind(c) + ! Length of icoeff + INTEGER(c_int), INTENT(in) :: num_gp + ! Number of dimensions in interpolation + INTEGER(c_int), INTENT(in) :: n_dim + ! Coordinates of grid points + REAL(c_double), DIMENSION(:,:), INTENT(in) :: gpc + ! Coordinates of observation + REAL(c_double), DIMENSION(:), INTENT(in) :: oc + ! Interpolation coefficients (num_gp) + REAL(c_double), DIMENSION(:), INTENT(inout) :: icoeff + + + call PDAFomi_get_interp_coeff_lin(num_gp, n_dim, gpc, oc, icoeff) + + END SUBROUTINE c__PDAFomi_get_interp_coeff_lin + + SUBROUTINE c__PDAFomi_init_dim_obs_l_iso(i_obs, coords_l, locweight, cradius, & + sradius, cnt_obs_l_all) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Coordinates of current analysis domain + REAL(c_double), DIMENSION(:), INTENT(in) :: coords_l + ! Type of localization function + INTEGER(c_int), INTENT(in) :: locweight + ! Localization cut-off radius + REAL(c_double), INTENT(in) :: cradius + ! Support radius of localization function + REAL(c_double), INTENT(in) :: sradius + ! Local dimension of current observation vector + INTEGER(c_int), INTENT(inout) :: cnt_obs_l_all + + + call PDAFomi_init_dim_obs_l_iso(thisobs_l(i_obs), thisobs(i_obs), & + coords_l, locweight, cradius, sradius, cnt_obs_l_all) + + END SUBROUTINE c__PDAFomi_init_dim_obs_l_iso + + SUBROUTINE c__PDAFomi_init_dim_obs_l_noniso(i_obs, coords_l, locweight, cradius, & + sradius, cnt_obs_l_all) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Coordinates of current analysis domain + REAL(c_double), DIMENSION(:), INTENT(in) :: coords_l + ! Type of localization function + INTEGER(c_int), INTENT(in) :: locweight + ! Vector of localization cut-off radii + REAL(c_double), DIMENSION(:), INTENT(in) :: cradius + ! Vector of support radii of localization function + REAL(c_double), DIMENSION(:), INTENT(in) :: sradius + ! Local dimension of current observation vector + INTEGER(c_int), INTENT(inout) :: cnt_obs_l_all + + + call PDAFomi_init_dim_obs_l_noniso(thisobs_l(i_obs), thisobs(i_obs), & + coords_l, locweight, cradius, sradius, cnt_obs_l_all) + + END SUBROUTINE c__PDAFomi_init_dim_obs_l_noniso + + SUBROUTINE c__PDAFomi_init_dim_obs_l_noniso_locweights(i_obs, coords_l, locweights, & + cradius, sradius, cnt_obs_l) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Coordinates of current analysis domain + REAL(c_double), DIMENSION(:), INTENT(in) :: coords_l + ! Types of localization function + INTEGER(c_int), DIMENSION(:), INTENT(in) :: locweights + ! Vector of localization cut-off radii + REAL(c_double), DIMENSION(:), INTENT(in) :: cradius + ! Vector of support radii of localization function + REAL(c_double), DIMENSION(:), INTENT(in) :: sradius + ! Local dimension of current observation vector + INTEGER(c_int), INTENT(inout) :: cnt_obs_l + + + call PDAFomi_init_dim_obs_l_noniso_locweights(thisobs_l(i_obs), & + thisobs(i_obs), coords_l, locweights, cradius, sradius, cnt_obs_l) + + END SUBROUTINE c__PDAFomi_init_dim_obs_l_noniso_locweights + + SUBROUTINE c__PDAFomi_obs_op_gridpoint(i_obs, state_p, obs_f_all) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! PE-local model state (dim_p) + REAL(c_double), DIMENSION(:), INTENT(in) :: state_p + ! Full observed state for all observation types (nobs_f_all) + REAL(c_double), DIMENSION(:), INTENT(inout) :: obs_f_all + + + call PDAFomi_obs_op_gridpoint(thisobs(i_obs), state_p, obs_f_all) + + END SUBROUTINE c__PDAFomi_obs_op_gridpoint + + SUBROUTINE c__PDAFomi_obs_op_gridavg(i_obs, nrows, state_p, obs_f_all) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Number of values to be averaged + INTEGER(c_int), INTENT(in) :: nrows + ! PE-local model state (dim_p) + REAL(c_double), DIMENSION(:), INTENT(in) :: state_p + ! Full observed state for all observation types (nobs_f_all) + REAL(c_double), DIMENSION(:), INTENT(inout) :: obs_f_all + + + call PDAFomi_obs_op_gridavg(thisobs(i_obs), nrows, state_p, obs_f_all) + + END SUBROUTINE c__PDAFomi_obs_op_gridavg + + SUBROUTINE c__PDAFomi_obs_op_extern(i_obs, ostate_p, obs_f_all) bind(c) + IMPLICIT NONE + !< Data type with full observation + INTEGER(c_int), INTENT(in) :: i_obs + !< PE-local observed model state (dim: thisobs%dim_obs_p) + REAL(c_double), DIMENSION(:), INTENT(in) :: ostate_p + !< Full observed state for all observation types (nobs_f_all) + REAL(c_double), DIMENSION(:), INTENT(inout) :: obs_f_all + + call PDAFomi_obs_op_extern(thisobs(i_obs), ostate_p, obs_f_all) + END SUBROUTINE c__PDAFomi_obs_op_extern + + SUBROUTINE c__PDAFomi_obs_op_interp_lin(i_obs, nrows, state_p, obs_f_all) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Number of values to be averaged + INTEGER(c_int), INTENT(in) :: nrows + ! PE-local model state (dim_p) + REAL(c_double), DIMENSION(:), INTENT(in) :: state_p + ! Full observed state for all observation types (nobs_f_all) + REAL(c_double), DIMENSION(:), INTENT(inout) :: obs_f_all + + + call PDAFomi_obs_op_interp_lin(thisobs(i_obs), nrows, state_p, obs_f_all) + + END SUBROUTINE c__PDAFomi_obs_op_interp_lin + + SUBROUTINE c__PDAFomi_obs_op_adj_gridpoint(i_obs, obs_f_all, state_p) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Full observed state for all observation types (nobs_f_all) + REAL(c_double), DIMENSION(:), INTENT(in) :: obs_f_all + ! PE-local model state (dim_p) + REAL(c_double), DIMENSION(:), INTENT(inout) :: state_p + + + call PDAFomi_obs_op_adj_gridpoint(thisobs(i_obs), obs_f_all, state_p) + + END SUBROUTINE c__PDAFomi_obs_op_adj_gridpoint + + SUBROUTINE c__PDAFomi_obs_op_adj_gridavg(i_obs, nrows, obs_f_all, state_p) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Number of values to be averaged + INTEGER(c_int), INTENT(in) :: nrows + ! Full observed state for all observation types (nobs_f_all) + REAL(c_double), DIMENSION(:), INTENT(in) :: obs_f_all + ! PE-local model state (dim_p) + REAL(c_double), DIMENSION(:), INTENT(inout) :: state_p + + + call PDAFomi_obs_op_adj_gridavg(thisobs(i_obs), nrows, obs_f_all, state_p) + + END SUBROUTINE c__PDAFomi_obs_op_adj_gridavg + + SUBROUTINE c__PDAFomi_obs_op_adj_interp_lin(i_obs, nrows, obs_f_all, state_p) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Number of values to be averaged + INTEGER(c_int), INTENT(in) :: nrows + ! Full observed state for all observation types (nobs_f_all) + REAL(c_double), DIMENSION(:), INTENT(in) :: obs_f_all + ! PE-local model state (dim_p) + REAL(c_double), DIMENSION(:), INTENT(inout) :: state_p + + + call PDAFomi_obs_op_adj_interp_lin(thisobs(i_obs), nrows, obs_f_all, state_p) + + END SUBROUTINE c__PDAFomi_obs_op_adj_interp_lin + + SUBROUTINE c__PDAFomi_observation_localization_weights(i_obs, ncols, a_l, weight, & + verbose) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: ncols + ! Input matrix (thisobs_l%dim_obs_l, ncols) + REAL(c_double), DIMENSION(:, :), INTENT(in) :: a_l + ! > Localization weights + REAL(c_double), DIMENSION(thisobs_l(i_obs)%dim_obs_l), INTENT(out) :: weight + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAFomi_observation_localization_weights(thisobs_l(i_obs), & + thisobs(i_obs), ncols, a_l, weight, verbose) + + END SUBROUTINE c__PDAFomi_observation_localization_weights + + SUBROUTINE c__PDAFomi_set_debug_flag(debugval) bind(c) + ! Value for debugging flag + INTEGER(c_int), INTENT(in) :: debugval + + + call PDAFomi_set_debug_flag(debugval) + + END SUBROUTINE c__PDAFomi_set_debug_flag + + SUBROUTINE c__PDAFomi_set_dim_obs_l(i_obs, cnt_obs_l_all, cnt_obs_l) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Local dimension of observation vector over all obs. types + INTEGER(c_int), INTENT(inout) :: cnt_obs_l_all + ! Local dimension of single observation type vector + INTEGER(c_int), INTENT(inout) :: cnt_obs_l + + + call PDAFomi_set_dim_obs_l(thisobs_l(i_obs), thisobs(i_obs), & + cnt_obs_l_all, cnt_obs_l) + + END SUBROUTINE c__PDAFomi_set_dim_obs_l + + SUBROUTINE c__PDAFomi_set_localization(i_obs, cradius, sradius, locweight) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Localization cut-off radius + REAL(c_double), INTENT(in) :: cradius + ! Support radius of localization function + REAL(c_double), INTENT(in) :: sradius + ! Type of localization function + INTEGER(c_int), INTENT(in) :: locweight + + + call PDAFomi_set_localization(thisobs_l(i_obs), cradius, sradius, locweight) + + END SUBROUTINE c__PDAFomi_set_localization + + SUBROUTINE c__PDAFomi_set_localization_noniso(i_obs, nradii, cradius, sradius, & + locweight, locweight_v) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Number of radii to consider for localization + INTEGER(c_int), INTENT(in) :: nradii + ! Localization cut-off radius + REAL(c_double), DIMENSION(nradii), INTENT(in) :: cradius + ! Support radius of localization function + REAL(c_double), DIMENSION(nradii), INTENT(in) :: sradius + ! Type of localization function + INTEGER(c_int), INTENT(in) :: locweight + ! Type of localization function in vertical direction (only for nradii=3) + INTEGER(c_int), INTENT(in) :: locweight_v + + + call PDAFomi_set_localization_noniso(thisobs_l(i_obs), nradii, cradius, & + sradius, locweight, locweight_v) + + END SUBROUTINE c__PDAFomi_set_localization_noniso + + SUBROUTINE c__PDAFomi_set_localize_covar_iso(i_obs, dim, ncoords, coords, & + locweight, cradius, sradius) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! State dimension + INTEGER(c_int), INTENT(in) :: dim + ! number of coordinate directions + INTEGER(c_int), INTENT(in) :: ncoords + ! Coordinates of state vector elements + REAL(c_double), DIMENSION(:,:), INTENT(in) :: coords + ! Localization weight type + INTEGER(c_int), INTENT(in) :: locweight + ! localization radius + REAL(c_double), INTENT(in) :: cradius + ! support radius for weight functions + REAL(c_double), INTENT(in) :: sradius + + + call PDAFomi_set_localize_covar_iso(thisobs(i_obs), dim, ncoords, coords, & + locweight, cradius, sradius) + + END SUBROUTINE c__PDAFomi_set_localize_covar_iso + + SUBROUTINE c__PDAFomi_set_localize_covar_noniso(i_obs, dim, ncoords, coords, & + locweight, cradius, sradius) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! State dimension + INTEGER(c_int), INTENT(in) :: dim + ! number of coordinate directions + INTEGER(c_int), INTENT(in) :: ncoords + ! Coordinates of state vector elements + REAL(c_double), DIMENSION(:,:), INTENT(in) :: coords + ! Localization weight type + INTEGER(c_int), INTENT(in) :: locweight + ! Vector of localization cut-off radii + REAL(c_double), DIMENSION(:), INTENT(in) :: cradius + ! Vector of support radii of localization function + REAL(c_double), DIMENSION(:), INTENT(in) :: sradius + + + call PDAFomi_set_localize_covar_noniso(thisobs(i_obs), dim, ncoords, & + coords, locweight, cradius, sradius) + + END SUBROUTINE c__PDAFomi_set_localize_covar_noniso + + SUBROUTINE c__PDAFomi_set_localize_covar_noniso_locweights(i_obs, dim, ncoords, & + coords, locweights, cradius, sradius) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! State dimension + INTEGER(c_int), INTENT(in) :: dim + ! number of coordinate directions + INTEGER(c_int), INTENT(in) :: ncoords + ! Coordinates of state vector elements + REAL(c_double), DIMENSION(:,:), INTENT(in) :: coords + ! Types of localization function + INTEGER(c_int), DIMENSION(:), INTENT(in) :: locweights + ! Vector of localization cut-off radii + REAL(c_double), DIMENSION(:), INTENT(in) :: cradius + ! Vector of support radii of localization function + REAL(c_double), DIMENSION(:), INTENT(in) :: sradius + + + call PDAFomi_set_localize_covar_noniso_locweights(thisobs(i_obs), dim, & + ncoords, coords, locweights, cradius, sradius) + + END SUBROUTINE c__PDAFomi_set_localize_covar_noniso_locweights + + SUBROUTINE c__PDAFomi_set_obs_diag(diag) bind(c) + ! Value for observation diagnostics mode + INTEGER(c_int), INTENT(in) :: diag + + + call PDAFomi_set_obs_diag(diag) + + END SUBROUTINE c__PDAFomi_set_obs_diag + + SUBROUTINE c__PDAFomi_set_domain_limits(lim_coords) bind(c) + ! geographic coordinate array (1: longitude, 2: latitude) + REAL(c_double), DIMENSION(2,2), INTENT(in) :: lim_coords + + + call PDAFomi_set_domain_limits(lim_coords) + + END SUBROUTINE c__PDAFomi_set_domain_limits + + SUBROUTINE c__PDAFomi_get_domain_limits_unstr(npoints_p, coords_p) bind(c) + ! number of process-local grid points + INTEGER(c_int), INTENT(in) :: npoints_p + ! geographic coordinate array (row 1: longitude, 2: latitude) + REAL(c_double), DIMENSION(:,:), INTENT(in) :: coords_p + + + call PDAFomi_get_domain_limits_unstr(npoints_p, coords_p) + + END SUBROUTINE c__PDAFomi_get_domain_limits_unstr + + SUBROUTINE c__PDAFomi_store_obs_l_index(i_obs, idx, id_obs_l, distance, cradius_l, & + sradius_l) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Element of local observation array to be filled + INTEGER(c_int), INTENT(in) :: idx + ! Index of local observation in full observation array + INTEGER(c_int), INTENT(in) :: id_obs_l + ! Distance between local analysis domain and observation + REAL(c_double), INTENT(in) :: distance + ! cut-off radius for this local observation + REAL(c_double), INTENT(in) :: cradius_l + ! support radius for this local observation + REAL(c_double), INTENT(in) :: sradius_l + + + call PDAFomi_store_obs_l_index(thisobs_l(i_obs), idx, id_obs_l, distance, & + cradius_l, sradius_l) + + END SUBROUTINE c__PDAFomi_store_obs_l_index + + SUBROUTINE c__PDAFomi_store_obs_l_index_vdist(i_obs, idx, id_obs_l, distance, & + cradius_l, sradius_l, vdist) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Element of local observation array to be filled + INTEGER(c_int), INTENT(in) :: idx + ! Index of local observation in full observation array + INTEGER(c_int), INTENT(in) :: id_obs_l + ! Distance between local analysis domain and observation + REAL(c_double), INTENT(in) :: distance + ! cut-off radius for this local observation + REAL(c_double), INTENT(in) :: cradius_l + ! support radius for this local observation + REAL(c_double), INTENT(in) :: sradius_l + ! support radius in vertical direction for 2+1D factorized localization + REAL(c_double), INTENT(in) :: vdist + + + call PDAFomi_store_obs_l_index_vdist(thisobs_l(i_obs), idx, id_obs_l, & + distance, cradius_l, sradius_l, vdist) + + END SUBROUTINE c__PDAFomi_store_obs_l_index_vdist +end module pdafomi_c \ No newline at end of file diff --git a/pyPDAF/source/src/fortran/pdafomi_c_assim.f90 b/pyPDAF/source/src/fortran/pdafomi_c_assim.f90 new file mode 100644 index 0000000000000000000000000000000000000000..db54a7ecb881b84ca058db0c3f7471283c8e9d88 --- /dev/null +++ b/pyPDAF/source/src/fortran/pdafomi_c_assim.f90 @@ -0,0 +1,1107 @@ + +MODULE pdafomi_c_assim +use iso_c_binding, only: c_double, c_int, c_bool +use PDAF +use pdaf_c_cb_interface +use pdaf_c_f_interface + +implicit none + +contains + SUBROUTINE c__PDAFomi_assimilate_local_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdafomi, obs_op_pdafomi, & + prepoststep_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdafomi, prodrinva_l_pdafomi, g2l_state_pdaf, & + l2g_state_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdafomi + ! Provide product of inverse of R with matrix A + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdafomi + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: g2l_state_pdaf + ! Init full state from local state + procedure(c__l2g_state_pdaf) :: l2g_state_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdafomi + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdafomi + g2l_state_pdaf_c_ptr => g2l_state_pdaf + l2g_state_pdaf_c_ptr => l2g_state_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_local_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__prepoststep_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__prodrinva_l_pdaf, f__g2l_state_pdaf, & + f__l2g_state_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_local_nondiagR + + SUBROUTINE c__PDAFomi_assimilate_global_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, prodrinva_pdaf, & + prepoststep_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_global_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, & + f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_global_nondiagR + + SUBROUTINE c__PDAFomi_assimilate_enkf_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdafomi, obs_op_pdafomi, & + add_obs_error_pdafomi, init_obscovar_pdafomi, prepoststep_pdaf, & + next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! Add observation error covariance matrix + procedure(c__add_obs_err_pdaf) :: add_obs_error_pdafomi + ! Initialize mean observation error variance + procedure(c__init_obs_covar_pdaf) :: init_obscovar_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + add_obs_err_pdaf_c_ptr => add_obs_error_pdafomi + init_obs_covar_pdaf_c_ptr => init_obscovar_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_enkf_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__add_obs_err_pdaf, f__init_obs_covar_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_enkf_nondiagR + + SUBROUTINE c__PDAFomi_assimilate_lenkf_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdafomi, obs_op_pdafomi, & + prepoststep_pdaf, localize_covar_pdafomi, add_obs_error_pdafomi, & + init_obscovar_pdafomi, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Apply localization to HP and HPH^T + procedure(c__localize_covar_pdaf) :: localize_covar_pdafomi + ! Provide product R^-1 A + procedure(c__add_obs_err_pdaf) :: add_obs_error_pdafomi + ! Initialize mean observation error variance + procedure(c__init_obs_covar_pdaf) :: init_obscovar_pdafomi + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + localize_covar_pdaf_c_ptr => localize_covar_pdafomi + add_obs_err_pdaf_c_ptr => add_obs_error_pdafomi + init_obs_covar_pdaf_c_ptr => init_obscovar_pdafomi + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_lenkf_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__prepoststep_pdaf, f__localize_covar_pdaf, f__add_obs_err_pdaf, & + f__init_obs_covar_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_lenkf_nondiagR + + SUBROUTINE c__PDAFomi_assimilate_nonlin_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdafomi, obs_op_pdafomi, & + likelihood_pdafomi, prepoststep_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! Compute likelihood + procedure(c__likelihood_pdaf) :: likelihood_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + likelihood_pdaf_c_ptr => likelihood_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_nonlin_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__likelihood_pdaf, f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_nonlin_nondiagR + + SUBROUTINE c__PDAFomi_assimilate_lnetf_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdafomi, obs_op_pdafomi, & + prepoststep_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdafomi, likelihood_l_pdafomi, g2l_state_pdaf, & + l2g_state_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdafomi + ! Compute likelihood and apply localization + procedure(c__likelihood_l_pdaf) :: likelihood_l_pdafomi + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: g2l_state_pdaf + ! Init full state from local state + procedure(c__l2g_state_pdaf) :: l2g_state_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdafomi + likelihood_l_pdaf_c_ptr => likelihood_l_pdafomi + g2l_state_pdaf_c_ptr => g2l_state_pdaf + l2g_state_pdaf_c_ptr => l2g_state_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_lnetf_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__prepoststep_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__likelihood_l_pdaf, f__g2l_state_pdaf, & + f__l2g_state_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_lnetf_nondiagR + + SUBROUTINE c__PDAFomi_assimilate_lknetf_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdafomi, obs_op_pdafomi, & + prepoststep_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdafomi, prodrinva_l_pdafomi, prodrinva_hyb_l_pdafomi, & + likelihood_l_pdafomi, likelihood_hyb_l_pdafomi, g2l_state_pdaf, & + l2g_state_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdafomi + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdafomi + ! Product R^-1 A on local analysis domain with hybrid weight + procedure(c__prodrinva_hyb_l_pdaf) :: prodrinva_hyb_l_pdafomi + ! Compute likelihood and apply localization + procedure(c__likelihood_l_pdaf) :: likelihood_l_pdafomi + ! Compute likelihood and apply localization with tempering + procedure(c__likelihood_hyb_l_pdaf) :: likelihood_hyb_l_pdafomi + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: g2l_state_pdaf + ! Init full state from local state + procedure(c__l2g_state_pdaf) :: l2g_state_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdafomi + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdafomi + prodrinva_hyb_l_pdaf_c_ptr => prodrinva_hyb_l_pdafomi + likelihood_l_pdaf_c_ptr => likelihood_l_pdafomi + likelihood_hyb_l_pdaf_c_ptr => likelihood_hyb_l_pdafomi + g2l_state_pdaf_c_ptr => g2l_state_pdaf + l2g_state_pdaf_c_ptr => l2g_state_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_lknetf_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__prepoststep_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__prodrinva_l_pdaf, f__prodrinva_hyb_l_pdaf, & + f__likelihood_l_pdaf, f__likelihood_hyb_l_pdaf, f__g2l_state_pdaf, & + f__l2g_state_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_lknetf_nondiagR + + SUBROUTINE c__PDAFomi_assimilate_local(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_f_pdaf, obs_op_f_pdaf, & + prepoststep_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, g2l_state_pdaf, l2g_state_pdaf, & + next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_f_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_f_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: g2l_state_pdaf + ! Init full state from local state + procedure(c__l2g_state_pdaf) :: l2g_state_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_f_pdaf_c_ptr => init_dim_obs_f_pdaf + obs_op_f_pdaf_c_ptr => obs_op_f_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + g2l_state_pdaf_c_ptr => g2l_state_pdaf + l2g_state_pdaf_c_ptr => l2g_state_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_local(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, f__prepoststep_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__g2l_state_pdaf, f__l2g_state_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_local + + SUBROUTINE c__PDAFomi_assimilate_global(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, prepoststep_pdaf, & + next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_global(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_global + + SUBROUTINE c__PDAFomi_assimilate_lenkf(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, prepoststep_pdaf, & + localize_covar_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Apply localization to HP and HPH^T + procedure(c__localize_covar_pdaf) :: localize_covar_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + localize_covar_pdaf_c_ptr => localize_covar_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_lenkf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prepoststep_pdaf, f__localize_covar_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_lenkf + + SUBROUTINE c__PDAFomi_assimilate_ensrf(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, prepoststep_pdaf, & + localize_covar_serial_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Apply localization to HP and BXY + procedure(c__localize_covar_serial_pdaf) :: localize_covar_serial_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + localize_covar_serial_pdaf_c_ptr => localize_covar_serial_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_ensrf(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prepoststep_pdaf, & + f__localize_covar_serial_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_ensrf + + SUBROUTINE c__PDAFomi_assimilate_3dvar(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, cvt_pdaf, & + cvt_adj_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, prepoststep_pdaf, & + next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_3dvar(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_3dvar + + SUBROUTINE c__PDAFomi_assimilate_en3dvar_estkf(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, prepoststep_pdaf, & + next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_en3dvar_estkf(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_en3dvar_estkf + + SUBROUTINE c__PDAFomi_assimilate_en3dvar_lestkf(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_f_pdaf, obs_op_f_pdaf, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, init_n_domains_pdaf, & + init_dim_l_pdaf, init_dim_obs_l_pdaf, g2l_state_pdaf, l2g_state_pdaf, & + prepoststep_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_f_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_f_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: g2l_state_pdaf + ! Init full state from local state + procedure(c__l2g_state_pdaf) :: l2g_state_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_f_pdaf_c_ptr => init_dim_obs_f_pdaf + obs_op_f_pdaf_c_ptr => obs_op_f_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + g2l_state_pdaf_c_ptr => g2l_state_pdaf + l2g_state_pdaf_c_ptr => l2g_state_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_en3dvar_lestkf(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, & + f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__g2l_state_pdaf, f__l2g_state_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_en3dvar_lestkf + + SUBROUTINE c__PDAFomi_assimilate_hyb3dvar_estkf(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdaf, obs_op_pdaf, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, & + obs_op_adj_pdaf, prepoststep_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply ensemble control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint ensemble control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_hyb3dvar_estkf(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_hyb3dvar_estkf + + SUBROUTINE c__PDAFomi_assimilate_hyb3dvar_lestkf(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_f_pdaf, obs_op_f_pdaf, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, & + obs_op_adj_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, g2l_state_pdaf, l2g_state_pdaf, prepoststep_pdaf, & + next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_f_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_f_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: g2l_state_pdaf + ! Init full state from local state + procedure(c__l2g_state_pdaf) :: l2g_state_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_f_pdaf_c_ptr => init_dim_obs_f_pdaf + obs_op_f_pdaf_c_ptr => obs_op_f_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + g2l_state_pdaf_c_ptr => g2l_state_pdaf + l2g_state_pdaf_c_ptr => l2g_state_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_hyb3dvar_lestkf(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, & + f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, f__l2g_state_pdaf, & + f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_hyb3dvar_lestkf + + SUBROUTINE c__PDAFomi_assimilate_3dvar_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdafomi, obs_op_pdafomi, & + prodrinva_pdafomi, cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdafomi, & + obs_op_adj_pdafomi, prepoststep_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdafomi + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdafomi + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prodrinva_pdaf_c_ptr => prodrinva_pdafomi + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdafomi + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_3dvar_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__prodrinva_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_3dvar_nondiagR + + SUBROUTINE c__PDAFomi_assimilate_en3dvar_estkf_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdafomi, obs_op_pdafomi, & + prodrinva_pdafomi, cvt_ens_pdaf, cvt_adj_ens_pdaf, obs_op_lin_pdafomi, & + obs_op_adj_pdafomi, prepoststep_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdafomi + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdafomi + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prodrinva_pdaf_c_ptr => prodrinva_pdafomi + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdafomi + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_en3dvar_estkf_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__prodrinva_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_en3dvar_estkf_nondiagR + + SUBROUTINE c__PDAFomi_assimilate_en3dvar_lestkf_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdafomi, obs_op_pdafomi, & + prodrinva_pdafomi, cvt_ens_pdaf, cvt_adj_ens_pdaf, obs_op_lin_pdafomi, & + obs_op_adj_pdafomi, prodrinva_l_pdafomi, init_n_domains_pdaf, & + init_dim_l_pdaf, init_dim_obs_l_pdafomi, g2l_state_pdaf, l2g_state_pdaf, & + prepoststep_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdafomi + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdafomi + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdafomi + ! Provide product R^-1 A with localization + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdafomi + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdafomi + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: g2l_state_pdaf + ! Init full state from local state + procedure(c__l2g_state_pdaf) :: l2g_state_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prodrinva_pdaf_c_ptr => prodrinva_pdafomi + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdafomi + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdafomi + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdafomi + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdafomi + g2l_state_pdaf_c_ptr => g2l_state_pdaf + l2g_state_pdaf_c_ptr => l2g_state_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_en3dvar_lestkf_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__prodrinva_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, & + f__l2g_state_pdaf, f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_en3dvar_lestkf_nondiagR + + SUBROUTINE c__PDAFomi_assimilate_hyb3dvar_estkf_nondiagR(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_pdafomi, obs_op_pdafomi, & + prodrinva_pdafomi, cvt_ens_pdaf, cvt_adj_ens_pdaf, cvt_pdaf, & + cvt_adj_pdaf, obs_op_lin_pdafomi, obs_op_adj_pdafomi, prepoststep_pdaf, & + next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdafomi + ! Apply ensemble control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint ensemble control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdafomi + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prodrinva_pdaf_c_ptr => prodrinva_pdafomi + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdafomi + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_hyb3dvar_estkf_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__prodrinva_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__cvt_pdaf, & + f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_hyb3dvar_estkf_nondiagR + + SUBROUTINE c__PDAFomi_assimilate_hyb3dvar_lestkf_nondiagR( & + collect_state_pdaf, distribute_state_pdaf, init_dim_obs_pdafomi, & + obs_op_pdafomi, prodrinva_pdafomi, cvt_ens_pdaf, cvt_adj_ens_pdaf, & + cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdafomi, obs_op_adj_pdafomi, & + prodrinva_l_pdafomi, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdafomi, g2l_state_pdaf, l2g_state_pdaf, prepoststep_pdaf, & + next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdafomi + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdafomi + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdafomi + ! Provide product R^-1 A + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdafomi + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdafomi + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: g2l_state_pdaf + ! Init full state from local state + procedure(c__l2g_state_pdaf) :: l2g_state_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prodrinva_pdaf_c_ptr => prodrinva_pdafomi + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdafomi + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdafomi + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdafomi + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdafomi + g2l_state_pdaf_c_ptr => g2l_state_pdaf + l2g_state_pdaf_c_ptr => l2g_state_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_assimilate_hyb3dvar_lestkf_nondiagR(f__collect_state_pdaf, & + f__distribute_state_pdaf, f__init_dim_obs_pdaf, f__obs_op_pdaf, & + f__prodrinva_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, f__cvt_pdaf, & + f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, f__l2g_state_pdaf, & + f__prepoststep_pdaf, f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_assimilate_hyb3dvar_lestkf_nondiagR + + SUBROUTINE c__PDAFomi_generate_obs(collect_state_pdaf, & + distribute_state_pdaf, init_dim_obs_f_pdaf, obs_op_f_pdaf, & + get_obs_f_pdaf, prepoststep_pdaf, next_observation_pdaf, outflag) bind(c) + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Routine to distribute a state vector + procedure(c__distribute_state_pdaf) :: distribute_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_f_pdaf + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_f_pdaf + ! Initialize observation vector + procedure(c__get_obs_f_pdaf) :: get_obs_f_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide time step, time and dimension of next observation + procedure(c__next_observation_pdaf) :: next_observation_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + distribute_state_pdaf_c_ptr => distribute_state_pdaf + init_dim_obs_f_pdaf_c_ptr => init_dim_obs_f_pdaf + obs_op_f_pdaf_c_ptr => obs_op_f_pdaf + get_obs_f_pdaf_c_ptr => get_obs_f_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + next_observation_pdaf_c_ptr => next_observation_pdaf + + call PDAFomi_generate_obs(f__collect_state_pdaf, f__distribute_state_pdaf, & + f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, f__get_obs_f_pdaf, f__prepoststep_pdaf, & + f__next_observation_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_generate_obs +END MODULE pdafomi_c_assim diff --git a/pyPDAF/source/src/fortran/pdafomi_c_diag.f90 b/pyPDAF/source/src/fortran/pdafomi_c_diag.f90 new file mode 100644 index 0000000000000000000000000000000000000000..e4294c178fc39215995c71c1b2a07e17ca485837 --- /dev/null +++ b/pyPDAF/source/src/fortran/pdafomi_c_diag.f90 @@ -0,0 +1,102 @@ +module pdafomi_c_diag +use iso_c_binding, only: c_int, c_double, c_bool +use PDAF +implicit none + +contains + SUBROUTINE c__PDAFomi_diag_dimobs(dim_obs_ptr) bind(c) + ! Pointer to observation dimensions + INTEGER(c_int), POINTER, DIMENSION(:), INTENT(inout) :: dim_obs_ptr + + + call PDAFomi_diag_dimobs(dim_obs_ptr) + END SUBROUTINE c__PDAFomi_diag_dimobs + + SUBROUTINE c__PDAFomi_diag_get_HX(id_obs, dim_obs_diag, hx_p_ptr) bind(c) + ! Index of observation type to return + INTEGER(c_int), INTENT(in) :: id_obs + ! Observation dimension + INTEGER(c_int), INTENT(out) :: dim_obs_diag + ! Pointer to observed ensemble mean + REAL(c_double), POINTER, DIMENSION(:,:), INTENT(out) :: hx_p_ptr + + + call PDAFomi_diag_get_HX(id_obs, dim_obs_diag, hx_p_ptr) + END SUBROUTINE c__PDAFomi_diag_get_HX + + SUBROUTINE c__PDAFomi_diag_get_HXmean(id_obs, dim_obs_diag, & + hxmean_p_ptr) bind(c) + ! Index of observation type to return + INTEGER(c_int), INTENT(in) :: id_obs + ! Observation dimension + INTEGER(c_int), INTENT(out) :: dim_obs_diag + ! Pointer to observed ensemble mean + REAL(c_double), POINTER, DIMENSION(:), INTENT(out) :: hxmean_p_ptr + + + call PDAFomi_diag_get_HXmean(id_obs, dim_obs_diag, hxmean_p_ptr) + END SUBROUTINE c__PDAFomi_diag_get_HXmean + + SUBROUTINE c__PDAFomi_diag_get_ivar(id_obs, dim_obs_diag, ivar_ptr) bind(c) + ! Index of observation type to return + INTEGER(c_int), INTENT(in) :: id_obs + ! Observation dimension + INTEGER(c_int), INTENT(out) :: dim_obs_diag + ! Pointer to inverse observation error variances + REAL(c_double), POINTER, DIMENSION(:), INTENT(out) :: ivar_ptr + + + call PDAFomi_diag_get_ivar(id_obs, dim_obs_diag, ivar_ptr) + END SUBROUTINE c__PDAFomi_diag_get_ivar + + SUBROUTINE c__PDAFomi_diag_get_obs(id_obs, dim_obs_diag, ncoord, obs_p_ptr, & + ocoord_p_ptr) bind(c) + ! Index of observation type to return + INTEGER(c_int), INTENT(in) :: id_obs + ! Observation dimension + INTEGER(c_int), INTENT(out) :: dim_obs_diag + ! Number of observation dimensions + INTEGER(c_int), INTENT(out) :: ncoord + ! Pointer to observation vector + REAL(c_double), POINTER, DIMENSION(:), INTENT(out) :: obs_p_ptr + ! Pointer to Coordinate array + REAL(c_double), POINTER, DIMENSION(:,:), INTENT(out) :: ocoord_p_ptr + + + call PDAFomi_diag_get_obs(id_obs, dim_obs_diag, ncoord, obs_p_ptr, & + ocoord_p_ptr) + END SUBROUTINE c__PDAFomi_diag_get_obs + + SUBROUTINE c__PDAFomi_diag_nobstypes(nobs) bind(c) + ! Number of observation types + INTEGER(c_int), INTENT(inout) :: nobs + + + call PDAFomi_diag_nobstypes(nobs) + + END SUBROUTINE c__PDAFomi_diag_nobstypes + + SUBROUTINE c__PDAFomi_diag_obs_rmsd(nobs, rmsd_pointer, verbose) bind(c) + ! Number of observation types + INTEGER(c_int), INTENT(inout) :: nobs + ! Vector of RMSD values + REAL(c_double), POINTER, DIMENSION(:), INTENT(inout) :: rmsd_pointer + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAFomi_diag_obs_rmsd(nobs, rmsd_pointer, verbose) + END SUBROUTINE c__PDAFomi_diag_obs_rmsd + + SUBROUTINE c__PDAFomi_diag_stats(nobs, obsstats_ptr, verbose) bind(c) + ! Number of observation types + INTEGER(c_int), INTENT(inout) :: nobs + ! Array of observation statistics + REAL(c_double), POINTER, DIMENSION(:,:), INTENT(inout) :: obsstats_ptr + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAFomi_diag_stats(nobs, obsstats_ptr, verbose) + END SUBROUTINE c__PDAFomi_diag_stats +end module pdafomi_c_diag diff --git a/pyPDAF/source/src/fortran/pdafomi_c_internal.f90 b/pyPDAF/source/src/fortran/pdafomi_c_internal.f90 new file mode 100644 index 0000000000000000000000000000000000000000..eae4a26a98bb8c6b64b92a76e2076f512ef38e93 --- /dev/null +++ b/pyPDAF/source/src/fortran/pdafomi_c_internal.f90 @@ -0,0 +1,726 @@ +module pdafomi_c_internal +use iso_c_binding, only: c_int, c_double, c_bool +use pdafomi_c, only: n_obs_omi, thisobs, thisobs_l +use pdafomi_obs_f +use pdafomi_obs_l +use PDAFomi_obs_op +use PDAFomi_dim_obs_l +use PDAFomi_obs_diag +implicit none +contains + SUBROUTINE c__PDAFomi_set_globalobs(globalobs_in) bind(c) + ! Input value of globalobs + INTEGER(c_int), INTENT(in) :: globalobs_in + + + call PDAFomi_set_globalobs(globalobs_in) + + END SUBROUTINE c__PDAFomi_set_globalobs + + SUBROUTINE c__PDAFomi_diag_omit_by_inno() bind(c) + call PDAFomi_diag_omit_by_inno() + + END SUBROUTINE c__PDAFomi_diag_omit_by_inno + + SUBROUTINE c__PDAFomi_cnt_dim_obs_l(i_obs, coords_l) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Coordinates of current analysis domain (thisobs%ncoord) + REAL(c_double), DIMENSION(:), INTENT(in) :: coords_l + + + call PDAFomi_cnt_dim_obs_l(thisobs_l(i_obs), thisobs(i_obs), coords_l) + + END SUBROUTINE c__PDAFomi_cnt_dim_obs_l + + SUBROUTINE c__PDAFomi_cnt_dim_obs_l_noniso(i_obs, coords_l) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Coordinates of current analysis domain (thisobs%ncoord) + REAL(c_double), DIMENSION(:), INTENT(in) :: coords_l + + + call PDAFomi_cnt_dim_obs_l_noniso(thisobs_l(i_obs), thisobs(i_obs), coords_l) + + END SUBROUTINE c__PDAFomi_cnt_dim_obs_l_noniso + + SUBROUTINE c__PDAFomi_init_obsarrays_l(i_obs, coords_l, off_obs_l_all) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Coordinates of current water column (thisobs%ncoord) + REAL(c_double), DIMENSION(:), INTENT(in) :: coords_l + ! input: offset of current obs. in local obs. vector + INTEGER(c_int), INTENT(inout) :: off_obs_l_all + + + call PDAFomi_init_obsarrays_l(thisobs_l(i_obs), thisobs(i_obs), coords_l, & + off_obs_l_all) + + END SUBROUTINE c__PDAFomi_init_obsarrays_l + + SUBROUTINE c__PDAFomi_init_obsarrays_l_noniso(i_obs, coords_l, off_obs_l_all) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Coordinates of current water column (thisobs%ncoord) + REAL(c_double), DIMENSION(:), INTENT(in) :: coords_l + ! input: offset of current obs. in local obs. vector + INTEGER(c_int), INTENT(inout) :: off_obs_l_all + + + call PDAFomi_init_obsarrays_l_noniso(thisobs_l(i_obs), thisobs(i_obs), & + coords_l, off_obs_l_all) + + END SUBROUTINE c__PDAFomi_init_obsarrays_l_noniso + + SUBROUTINE c__PDAFomi_g2l_obs(i_obs, obs_f_all, obs_l_all) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Full obs. vector of current obs. for all variables + REAL(c_double), DIMENSION(:), INTENT(in) :: obs_f_all + ! Local observation vector for all variables + REAL(c_double), DIMENSION(:), INTENT(inout) :: obs_l_all + + + call PDAFomi_g2l_obs(thisobs_l(i_obs), thisobs(i_obs), obs_f_all, obs_l_all) + + END SUBROUTINE c__PDAFomi_g2l_obs + + SUBROUTINE c__PDAFomi_init_obs_l(i_obs, obs_l_all) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Local observation vector for all variables + REAL(c_double), DIMENSION(:), INTENT(inout) :: obs_l_all + + + call PDAFomi_init_obs_l(thisobs_l(i_obs), thisobs(i_obs), obs_l_all) + + END SUBROUTINE c__PDAFomi_init_obs_l + + SUBROUTINE c__PDAFomi_init_obsvar_l(i_obs, meanvar_l, cnt_obs_l) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Mean variance + REAL(c_double), INTENT(inout) :: meanvar_l + ! Observation counter + INTEGER(c_int), INTENT(inout) :: cnt_obs_l + + + call PDAFomi_init_obsvar_l(thisobs_l(i_obs), thisobs(i_obs), meanvar_l, & + cnt_obs_l) + + END SUBROUTINE c__PDAFomi_init_obsvar_l + + SUBROUTINE c__PDAFomi_prodRinvA_l(i_obs, nobs_all, ncols, a_l, c_l, verbose) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Dimension of local obs. vector (all obs. types) + INTEGER(c_int), INTENT(in) :: nobs_all + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: ncols + ! Input matrix (thisobs_l%dim_obs_l, ncols) + REAL(c_double), DIMENSION(:, :), INTENT(inout) :: a_l + ! Output matrix (thisobs_l%dim_obs_l, ncols) + REAL(c_double), DIMENSION(:, :), INTENT(out) :: c_l + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAFomi_prodRinvA_l(thisobs_l(i_obs), thisobs(i_obs), nobs_all, & + ncols, a_l, c_l, verbose) + + END SUBROUTINE c__PDAFomi_prodRinvA_l + + SUBROUTINE c__PDAFomi_prodRinvA_hyb_l(i_obs, nobs_all, ncols, gamma, a_l, c_l, & + verbose) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Dimension of local obs. vector (all obs. types) + INTEGER(c_int), INTENT(in) :: nobs_all + ! Rank of initial covariance matrix + INTEGER(c_int), INTENT(in) :: ncols + ! Hybrid weight + REAL(c_double), INTENT(in) :: gamma + ! Input matrix (thisobs_l%dim_obs_l, ncols) + REAL(c_double), DIMENSION(:, :), INTENT(inout) :: a_l + ! Output matrix (thisobs_l%dim_obs_l, ncols) + REAL(c_double), DIMENSION(:, :), INTENT(out) :: c_l + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAFomi_prodRinvA_hyb_l(thisobs_l(i_obs), thisobs(i_obs), nobs_all, & + ncols, gamma, a_l, c_l, verbose) + + END SUBROUTINE c__PDAFomi_prodRinvA_hyb_l + + SUBROUTINE c__PDAFomi_likelihood_l(i_obs, resid_l_all, lhood_l, verbose) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Input vector of residuum + REAL(c_double), DIMENSION(:), INTENT(inout) :: resid_l_all + ! Output vector - log likelihood + REAL(c_double), INTENT(inout) :: lhood_l + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAFomi_likelihood_l(thisobs_l(i_obs), thisobs(i_obs), resid_l_all, & + lhood_l, verbose) + + END SUBROUTINE c__PDAFomi_likelihood_l + + SUBROUTINE c__PDAFomi_likelihood_hyb_l(i_obs, resid_l_all, gamma, lhood_l, verbose) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Input vector of residuum + REAL(c_double), DIMENSION(:), INTENT(inout) :: resid_l_all + ! Hybrid weight + REAL(c_double), INTENT(in) :: gamma + ! Output vector - log likelihood + REAL(c_double), INTENT(inout) :: lhood_l + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAFomi_likelihood_hyb_l(thisobs_l(i_obs), thisobs(i_obs), & + resid_l_all, gamma, lhood_l, verbose) + + END SUBROUTINE c__PDAFomi_likelihood_hyb_l + + SUBROUTINE c__PDAFomi_g2l_obs_internal(i_obs, obs_f_one, offset_obs_l_all, & + obs_l_all) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Full obs. vector of current obs. type (nobs_f_one) + REAL(c_double), DIMENSION(:), INTENT(in) :: obs_f_one + ! Offset of current observation in obs_l_all and ivar_l_all + INTEGER(c_int), INTENT(in) :: offset_obs_l_all + ! Local observation vector for all variables (nobs_l_all) + REAL(c_double), DIMENSION(:), INTENT(inout) :: obs_l_all + + + call PDAFomi_g2l_obs_internal(thisobs_l(i_obs), obs_f_one, & + offset_obs_l_all, obs_l_all) + + END SUBROUTINE c__PDAFomi_g2l_obs_internal + + SUBROUTINE c__PDAFomi_comp_dist2(i_obs, coordsa, coordsb, distance2, & + verbose) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Coordinates of current analysis domain (ncoord) + REAL(c_double), DIMENSION(:), INTENT(in) :: coordsa + ! Coordinates of observation (ncoord) + REAL(c_double), DIMENSION(:), INTENT(in) :: coordsb + ! Squared distance + REAL(c_double), INTENT(out) :: distance2 + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAFomi_comp_dist2(thisobs(i_obs), coordsa, coordsb, distance2, verbose) + + END SUBROUTINE c__PDAFomi_comp_dist2 + + SUBROUTINE c__PDAFomi_check_dist2(i_obs, coordsa, coordsb, distance2, checkdist, & + verbose, cnt_obs) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Coordinates of current analysis domain (ncoord) + REAL(c_double), DIMENSION(:), INTENT(in) :: coordsa + ! Coordinates of observation (ncoord) + REAL(c_double), DIMENSION(:), INTENT(in) :: coordsb + ! Squared distance + REAL(c_double), INTENT(out) :: distance2 + ! Flag whether distance is within cut-off radius + LOGICAL(c_bool), INTENT(out) :: checkdist + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + ! Count number of local observations + INTEGER(c_int), INTENT(inout) :: cnt_obs + + logical :: checkdist_out + call PDAFomi_check_dist2(thisobs(i_obs), thisobs_l(i_obs), coordsa, & + coordsb, distance2, checkdist_out, verbose, cnt_obs) + checkdist = checkdist_out + END SUBROUTINE c__PDAFomi_check_dist2 + + SUBROUTINE c__PDAFomi_check_dist2_noniso(i_obs, coordsa, coordsb, distance2, dists, & + cradius, sradius, checkdist, verbose, cnt_obs) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Coordinates of current analysis domain (ncoord) + REAL(c_double), DIMENSION(:), INTENT(in) :: coordsa + ! Coordinates of observation (ncoord) + REAL(c_double), DIMENSION(:), INTENT(in) :: coordsb + ! Squared distance + REAL(c_double), INTENT(out) :: distance2 + ! Vector of distance in each coordinate direction + REAL(c_double), DIMENSION(:), INTENT(inout) :: dists + ! Directional cut-off radius + REAL(c_double), INTENT(out) :: cradius + ! Directional support radius + REAL(c_double), INTENT(inout) :: sradius + ! Flag whether distance is within cut-off radius + LOGICAL(c_bool), INTENT(out) :: checkdist + ! Control screen output + INTEGER(c_int), INTENT(in) :: verbose + ! Count number of local observations + INTEGER(c_int), INTENT(inout) :: cnt_obs + + logical :: checkdist_out + + call PDAFomi_check_dist2_noniso(thisobs(i_obs), thisobs_l(i_obs), & + coordsa, coordsb, distance2, dists, cradius, sradius, checkdist_out, & + verbose, cnt_obs) + + checkdist = checkdist_out + END SUBROUTINE c__PDAFomi_check_dist2_noniso + + SUBROUTINE c__PDAFomi_weights_l(verbose, nobs_l, ncols, locweight, cradius, & + sradius, mata, ivar_obs_l, dist_l, weight_l) bind(c) + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: verbose + ! Number of local observations + INTEGER(c_int), INTENT(in) :: nobs_l + ! + INTEGER(c_int), INTENT(in) :: ncols + ! Localization weight type + INTEGER(c_int), INTENT(in) :: locweight + ! Localization cut-off radius + REAL(c_double), DIMENSION(:), INTENT(in) :: cradius + ! support radius for weight functions + REAL(c_double), DIMENSION(:), INTENT(in) :: sradius + ! + REAL(c_double), DIMENSION(:,:), INTENT(in) :: mata + ! Local vector of inverse obs. variances (nobs_l) + REAL(c_double), DIMENSION(:), INTENT(in) :: ivar_obs_l + ! Local vector of obs. distances (nobs_l) + REAL(c_double), DIMENSION(:), INTENT(in) :: dist_l + ! Output: vector of weights + REAL(c_double), DIMENSION(:), INTENT(out) :: weight_l + + + call PDAFomi_weights_l(verbose, nobs_l, ncols, locweight, cradius, & + sradius, mata, ivar_obs_l, dist_l, weight_l) + + END SUBROUTINE c__PDAFomi_weights_l + + SUBROUTINE c__PDAFomi_weights_l_sgnl(verbose, nobs_l, ncols, locweight, & + cradius, sradius, mata, ivar_obs_l, dist_l, weight_l) bind(c) + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: verbose + ! Number of local observations + INTEGER(c_int), INTENT(in) :: nobs_l + ! + INTEGER(c_int), INTENT(in) :: ncols + ! Localization weight type + INTEGER(c_int), INTENT(in) :: locweight + ! Localization cut-off radius + REAL(c_double), INTENT(in) :: cradius + ! support radius for weight functions + REAL(c_double), INTENT(in) :: sradius + ! + REAL(c_double), DIMENSION(:,:), INTENT(in) :: mata + ! Local vector of inverse obs. variances (nobs_l) + REAL(c_double), DIMENSION(:), INTENT(in) :: ivar_obs_l + ! Local vector of obs. distances (nobs_l) + REAL(c_double), DIMENSION(:), INTENT(in) :: dist_l + ! Output: vector of weights + REAL(c_double), DIMENSION(:), INTENT(out) :: weight_l + + + call PDAFomi_weights_l_sgnl(verbose, nobs_l, ncols, locweight, cradius, & + sradius, mata, ivar_obs_l, dist_l, weight_l) + + END SUBROUTINE c__PDAFomi_weights_l_sgnl + + SUBROUTINE c__PDAFomi_omit_by_inno_l(i_obs, inno_l, obs_l_all, obsid, cnt_all, & + verbose) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Input vector of observation innovation + REAL(c_double), DIMENSION(:), INTENT(in) :: inno_l + ! Input vector of local observations + REAL(c_double), DIMENSION(:), INTENT(in) :: obs_l_all + ! ID of observation type + INTEGER(c_int), INTENT(in) :: obsid + ! Count of omitted observation over all types + INTEGER(c_int), INTENT(inout) :: cnt_all + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAFomi_omit_by_inno_l(thisobs_l(i_obs), thisobs(i_obs), inno_l, & + obs_l_all, obsid, cnt_all, verbose) + + END SUBROUTINE c__PDAFomi_omit_by_inno_l + + SUBROUTINE c__PDAFomi_obsstats_l(screen) bind(c) + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + + call PDAFomi_obsstats_l(screen) + + END SUBROUTINE c__PDAFomi_obsstats_l + + SUBROUTINE c__PDAFomi_dealloc() bind(c) + call PDAFomi_dealloc() + + END SUBROUTINE c__PDAFomi_dealloc + + SUBROUTINE c__PDAFomi_ocoord_all(ncoord, oc_all) bind(c) + ! Number of coordinate directions + INTEGER(c_int), INTENT(in) :: ncoord + ! Array of observation coordinates size(ncoord, dim_obs) + REAL(c_double), DIMENSION(:,:), INTENT(out) :: oc_all + + + call PDAFomi_ocoord_all(ncoord, oc_all) + + END SUBROUTINE c__PDAFomi_ocoord_all + + SUBROUTINE c__PDAFomi_local_weight(wtype, rtype, cradius, sradius, distance, & + nrows, ncols, a, var_obs, weight, verbose) bind(c) + ! Type of weight function + INTEGER(c_int), INTENT(in) :: wtype + ! Type of regulated weighting + INTEGER(c_int), INTENT(in) :: rtype + ! Cut-off radius + REAL(c_double), INTENT(in) :: cradius + ! Support radius + REAL(c_double), INTENT(in) :: sradius + ! Distance to observation + REAL(c_double), INTENT(in) :: distance + ! Number of rows in matrix A + INTEGER(c_int), INTENT(in) :: nrows + ! Number of columns in matrix A + INTEGER(c_int), INTENT(in) :: ncols + ! Input matrix + REAL(c_double), DIMENSION(nrows, ncols), INTENT(in) :: a + ! Observation variance + REAL(c_double), INTENT(in) :: var_obs + ! Weights + REAL(c_double), INTENT(out) :: weight + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: verbose + + + call PDAFomi_local_weight(wtype, rtype, cradius, sradius, distance, & + nrows, ncols, a, var_obs, weight, verbose) + + END SUBROUTINE c__PDAFomi_local_weight + + SUBROUTINE c__PDAFomi_check_dist2_loop(i_obs, coordsa, cnt_obs, mode) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Coordinates of current analysis domain (ncoord) + REAL(c_double), DIMENSION(:), INTENT(in) :: coordsa + ! Count number of local observations + INTEGER(c_int), INTENT(inout) :: cnt_obs + ! 1: count local observations + INTEGER(c_int), INTENT(in) :: mode + + + call PDAFomi_check_dist2_loop(thisobs_l(i_obs), thisobs(i_obs), coordsa, & + cnt_obs, mode) + + END SUBROUTINE c__PDAFomi_check_dist2_loop + + SUBROUTINE c__PDAFomi_check_dist2_noniso_loop(i_obs, coordsa, cnt_obs, mode) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Coordinates of current analysis domain (ncoord) + REAL(c_double), DIMENSION(:), INTENT(in) :: coordsa + ! Count number of local observations + INTEGER(c_int), INTENT(inout) :: cnt_obs + ! 1: count local observations + INTEGER(c_int), INTENT(in) :: mode + + + call PDAFomi_check_dist2_noniso_loop(thisobs_l(i_obs), thisobs(i_obs), & + coordsa, cnt_obs, mode) + + END SUBROUTINE c__PDAFomi_check_dist2_noniso_loop + + SUBROUTINE c__PDAFomi_obs_op_gatheronly(i_obs, state_p, obs_f_all) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! PE-local model state (dim_p) + REAL(c_double), DIMENSION(:), INTENT(in) :: state_p + ! Full observed state for all observation types (nobs_f_all) + REAL(c_double), DIMENSION(:), INTENT(inout) :: obs_f_all + + + call PDAFomi_obs_op_gatheronly(thisobs(i_obs), state_p, obs_f_all) + + END SUBROUTINE c__PDAFomi_obs_op_gatheronly + + SUBROUTINE c__PDAFomi_obs_op_adj_gatheronly(i_obs, obs_f_all, state_p) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Full observed state for all observation types (nobs_f_all) + REAL(c_double), DIMENSION(:), INTENT(inout) :: obs_f_all + ! PE-local model state (dim_p) + REAL(c_double), DIMENSION(:), INTENT(in) :: state_p + + + call PDAFomi_obs_op_adj_gatheronly(thisobs(i_obs), obs_f_all, state_p) + + END SUBROUTINE c__PDAFomi_obs_op_adj_gatheronly + + SUBROUTINE c__PDAFomi_init_obs_f(i_obs, dim_obs_f, obsstate_f, offset) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Dimension of full observed state (all observed fields) + INTEGER(c_int), INTENT(in) :: dim_obs_f + ! Full observation vector (dim_obs_f) + REAL(c_double), DIMENSION(:), INTENT(inout) :: obsstate_f + ! input: offset of module-type observations in obsstate_f + INTEGER(c_int), INTENT(inout) :: offset + + + call PDAFomi_init_obs_f(thisobs(i_obs), dim_obs_f, obsstate_f, offset) + + END SUBROUTINE c__PDAFomi_init_obs_f + + SUBROUTINE c__PDAFomi_init_obsvars_f(i_obs, dim_obs_f, var_f, offset) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Dimension of full observed state (all observed fields) + INTEGER(c_int), INTENT(in) :: dim_obs_f + ! Full vector of observation variances (dim_obs_f) + REAL(c_double), DIMENSION(:), INTENT(inout) :: var_f + ! input: offset of module-type observations in obsstate_f + INTEGER(c_int), INTENT(inout) :: offset + + + call PDAFomi_init_obsvars_f(thisobs(i_obs), dim_obs_f, var_f, offset) + + END SUBROUTINE c__PDAFomi_init_obsvars_f + + SUBROUTINE c__PDAFomi_init_obsvar_f(i_obs, meanvar, cnt_obs) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Mean variance + REAL(c_double), INTENT(inout) :: meanvar + ! Observation counter + INTEGER(c_int), INTENT(inout) :: cnt_obs + + + call PDAFomi_init_obsvar_f(thisobs(i_obs), meanvar, cnt_obs) + + END SUBROUTINE c__PDAFomi_init_obsvar_f + + SUBROUTINE c__PDAFomi_prodRinvA(i_obs, ncols, a_p, c_p) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Number of columns in A_p and C_p + INTEGER(c_int), INTENT(in) :: ncols + ! Input matrix (nobs_f, ncols) + REAL(c_double), DIMENSION(:, :), INTENT(in) :: a_p + ! Output matrix (nobs_f, ncols) + REAL(c_double), DIMENSION(:, :), INTENT(out) :: c_p + + + call PDAFomi_prodRinvA(thisobs(i_obs), ncols, a_p, c_p) + + END SUBROUTINE c__PDAFomi_prodRinvA + + SUBROUTINE c__PDAFomi_likelihood(i_obs, resid, lhood) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Input vector of residuum + REAL(c_double), DIMENSION(:), INTENT(in) :: resid + ! Output vector - log likelihood + REAL(c_double), INTENT(inout) :: lhood + + + call PDAFomi_likelihood(thisobs(i_obs), resid, lhood) + + END SUBROUTINE c__PDAFomi_likelihood + + SUBROUTINE c__PDAFomi_add_obs_error(i_obs, nobs_all, matc) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Number of observations + INTEGER(c_int), INTENT(in) :: nobs_all + ! Input/Output matrix (nobs_f, rank) + REAL(c_double), DIMENSION(:, :), INTENT(inout) :: matc + + + call PDAFomi_add_obs_error(thisobs(i_obs), nobs_all, matc) + + END SUBROUTINE c__PDAFomi_add_obs_error + + SUBROUTINE c__PDAFomi_init_obscovar(i_obs, nobs_all, covar, isdiag) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Number of observations + INTEGER(c_int), INTENT(in) :: nobs_all + ! Input/Output matrix (nobs_all, nobs_all) + REAL(c_double), DIMENSION(:, :), INTENT(inout) :: covar + ! Whether matrix R is diagonal + LOGICAL(c_bool), INTENT(out) :: isdiag + + logical :: isdiag_out + + call PDAFomi_init_obscovar(thisobs(i_obs), nobs_all, covar, isdiag_out) + isdiag = isdiag_out + END SUBROUTINE c__PDAFomi_init_obscovar + + SUBROUTINE c__PDAFomi_init_obserr_f(i_obs, obserr_f) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Full vector of observation errors + REAL(c_double), DIMENSION(:), INTENT(inout) :: obserr_f + + + call PDAFomi_init_obserr_f(thisobs(i_obs), obserr_f) + + END SUBROUTINE c__PDAFomi_init_obserr_f + + SUBROUTINE c__PDAFomi_get_local_ids_obs_f(dim_obs_g, lradius, oc_f, cnt_lim, & + id_lim, disttype, domainsize) bind(c) + ! Global full number of observations + INTEGER(c_int), INTENT(in) :: dim_obs_g + ! Localization radius (used is a constant one here) + REAL(c_double), INTENT(in) :: lradius + ! observation coordinates (radians), row 1: lon, 2: lat + REAL(c_double), DIMENSION(:,:), INTENT(in) :: oc_f + ! Number of full observation for local process domain + INTEGER(c_int), INTENT(out) :: cnt_lim + ! Indices of process-local full obs. in global full vector + INTEGER(c_int), DIMENSION(:), INTENT(out) :: id_lim + ! type of distance computation + INTEGER(c_int), INTENT(in) :: disttype + ! Global size of model domain + REAL(c_double), DIMENSION(:), INTENT(in) :: domainsize + + + call PDAFomi_get_local_ids_obs_f(dim_obs_g, lradius, oc_f, cnt_lim, & + id_lim, disttype, domainsize) + + END SUBROUTINE c__PDAFomi_get_local_ids_obs_f + + SUBROUTINE c__PDAFomi_limit_obs_f(i_obs, offset, obs_f_one, obs_f_lim) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! offset of this observation in obs_f_lim + INTEGER(c_int), INTENT(in) :: offset + ! Global full observation vector (nobs_f) + REAL(c_double), DIMENSION(:), INTENT(in) :: obs_f_one + ! full observation vector for process domains (nobs_lim) + REAL(c_double), DIMENSION(:), INTENT(out) :: obs_f_lim + + + call PDAFomi_limit_obs_f(thisobs(i_obs), offset, obs_f_one, obs_f_lim) + + END SUBROUTINE c__PDAFomi_limit_obs_f + + SUBROUTINE c__PDAFomi_gather_dim_obs_f(dim_obs_p, dim_obs_f) bind(c) + ! PE-local observation dimension + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Full observation dimension + INTEGER(c_int), INTENT(out) :: dim_obs_f + + + call PDAFomi_gather_dim_obs_f(dim_obs_p, dim_obs_f) + + END SUBROUTINE c__PDAFomi_gather_dim_obs_f + + SUBROUTINE c__PDAFomi_gather_obs_f_flex(dim_obs_p, obs_p, obs_f, status) bind(c) + ! PE-local observation dimension + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! PE-local vector + REAL(c_double), DIMENSION(:), INTENT(in) :: obs_p + ! Full gathered vector + REAL(c_double), DIMENSION(:), INTENT(out) :: obs_f + ! Status flag: (0) no error + INTEGER(c_int), INTENT(out) :: status + + + call PDAFomi_gather_obs_f_flex(dim_obs_p, obs_p, obs_f, status) + + END SUBROUTINE c__PDAFomi_gather_obs_f_flex + + SUBROUTINE c__PDAFomi_gather_obs_f2_flex(dim_obs_p, coords_p, coords_f, & + nrows, status) bind(c) + ! PE-local observation dimension + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! PE-local array + REAL(c_double), DIMENSION(:,:), INTENT(in) :: coords_p + ! Full gathered array + REAL(c_double), DIMENSION(:,:), INTENT(out) :: coords_f + ! Number of rows in array + INTEGER(c_int), INTENT(in) :: nrows + ! Status flag: (0) no error + INTEGER(c_int), INTENT(out) :: status + + + call PDAFomi_gather_obs_f2_flex(dim_obs_p, coords_p, coords_f, nrows, status) + + END SUBROUTINE c__PDAFomi_gather_obs_f2_flex + + SUBROUTINE c__PDAFomi_omit_by_inno(i_obs, inno_f, obs_f_all, obsid, cnt_all) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Input vector of observation innovation + REAL(c_double), DIMENSION(:), INTENT(in) :: inno_f + ! Input vector of local observations + REAL(c_double), DIMENSION(:), INTENT(in) :: obs_f_all + ! ID of observation type + INTEGER(c_int), INTENT(in) :: obsid + ! Count of omitted observation over all types + INTEGER(c_int), INTENT(inout) :: cnt_all + + + call PDAFomi_omit_by_inno(thisobs(i_obs), inno_f, obs_f_all, obsid, cnt_all) + + END SUBROUTINE c__PDAFomi_omit_by_inno + + SUBROUTINE c__PDAFomi_obsstats(screen) bind(c) + ! Verbosity flag + INTEGER(c_int), INTENT(in) :: screen + + + call PDAFomi_obsstats(screen) + + END SUBROUTINE c__PDAFomi_obsstats + + SUBROUTINE c__PDAFomi_gather_obsdims() bind(c) + call PDAFomi_gather_obsdims() + + END SUBROUTINE c__PDAFomi_gather_obsdims +end module pdafomi_c_internal diff --git a/pyPDAF/source/src/fortran/pdafomi_c_legacy.f90 b/pyPDAF/source/src/fortran/pdafomi_c_legacy.f90 new file mode 100644 index 0000000000000000000000000000000000000000..d2f09a9f7520cc09d7c6912592df18261eec087b --- /dev/null +++ b/pyPDAF/source/src/fortran/pdafomi_c_legacy.f90 @@ -0,0 +1,250 @@ +module pdafomi_c_legacy +use iso_c_binding, only: c_int, c_double, c_bool +use pdafomi_c, only: n_obs_omi, thisobs, thisobs_l +use pdafomi_obs_l +implicit none +contains + SUBROUTINE c__PDAFomi_localize_covar_iso(i_obs, dim, locweight, cradius, sradius, & + coords, hp, hph) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! State dimension + INTEGER(c_int), INTENT(in) :: dim + ! Localization weight type + INTEGER(c_int), INTENT(in) :: locweight + ! localization radius + REAL(c_double), INTENT(in) :: cradius + ! support radius for weight functions + REAL(c_double), INTENT(in) :: sradius + ! Coordinates of state vector elements + REAL(c_double), DIMENSION(:,:), INTENT(in) :: coords + ! Matrix HP, dimension (nobs, dim) + REAL(c_double), DIMENSION(:, :), INTENT(inout) :: hp + ! Matrix HPH, dimension (nobs, nobs) + REAL(c_double), DIMENSION(:, :), INTENT(inout) :: hph + + + call PDAFomi_localize_covar_iso(thisobs(i_obs), dim, locweight, cradius, & + sradius, coords, hp, hph) + + END SUBROUTINE c__PDAFomi_localize_covar_iso + + SUBROUTINE c__PDAFomi_localize_covar_noniso_locweights(i_obs, dim, locweights, & + cradius, sradius, coords, hp, hph) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! State dimension + INTEGER(c_int), INTENT(in) :: dim + ! Types of localization function + INTEGER(c_int), DIMENSION(:), INTENT(in) :: locweights + ! Vector of localization cut-off radii + REAL(c_double), DIMENSION(:), INTENT(in) :: cradius + ! Vector of support radii of localization function + REAL(c_double), DIMENSION(:), INTENT(in) :: sradius + ! Coordinates of state vector elements + REAL(c_double), DIMENSION(:,:), INTENT(in) :: coords + ! Matrix HP, dimension (nobs, dim) + REAL(c_double), DIMENSION(:, :), INTENT(inout) :: hp + ! Matrix HPH, dimension (nobs, nobs) + REAL(c_double), DIMENSION(:, :), INTENT(inout) :: hph + + + call PDAFomi_localize_covar_noniso_locweights(thisobs(i_obs), dim, & + locweights, cradius, sradius, coords, hp, hph) + + END SUBROUTINE c__PDAFomi_localize_covar_noniso_locweights + + SUBROUTINE c__PDAFomi_localize_covar_noniso(i_obs, dim, locweight, cradius, & + sradius, coords, hp, hph) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! State dimension + INTEGER(c_int), INTENT(in) :: dim + ! Localization weight type + INTEGER(c_int), INTENT(in) :: locweight + ! Vector of localization cut-off radii + REAL(c_double), DIMENSION(:), INTENT(in) :: cradius + ! Vector of support radii of localization function + REAL(c_double), DIMENSION(:), INTENT(in) :: sradius + ! Coordinates of state vector elements + REAL(c_double), DIMENSION(:,:), INTENT(in) :: coords + ! Matrix HP, dimension (nobs, dim) + REAL(c_double), DIMENSION(:, :), INTENT(inout) :: hp + ! Matrix HPH, dimension (nobs, nobs) + REAL(c_double), DIMENSION(:, :), INTENT(inout) :: hph + + + call PDAFomi_localize_covar_noniso(thisobs(i_obs), dim, locweight, & + cradius, sradius, coords, hp, hph) + + END SUBROUTINE c__PDAFomi_localize_covar_noniso + + SUBROUTINE c__PDAFomi_localize_covar_serial_iso(i_obs, iobs_all, dim, dim_obs, & + locweight, cradius, sradius, coords, hp, hxy) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Index of current observation + INTEGER(c_int), INTENT(in) :: iobs_all + ! State dimension + INTEGER(c_int), INTENT(in) :: dim + ! Overall full observation dimension + INTEGER(c_int), INTENT(in) :: dim_obs + ! Localization weight type + INTEGER(c_int), INTENT(in) :: locweight + ! localization radius + REAL(c_double), INTENT(in) :: cradius + ! support radius for weight functions + REAL(c_double), INTENT(in) :: sradius + ! Coordinates of state vector elements + REAL(c_double), DIMENSION(:,:), INTENT(in) :: coords + ! Vector HP, dimension (dim) + REAL(c_double), DIMENSION(:), INTENT(inout) :: hp + ! Matrix HXY, dimension (nobs) + REAL(c_double), DIMENSION(:), INTENT(inout) :: hxy + + + call PDAFomi_localize_covar_serial_iso(thisobs(i_obs), iobs_all, dim, & + dim_obs, locweight, cradius, sradius, coords, hp, hxy) + + END SUBROUTINE c__PDAFomi_localize_covar_serial_iso + + SUBROUTINE c__PDAFomi_localize_covar_serial_noniso_locweights(i_obs, iobs_all, dim, & + dim_obs, locweights, cradius, sradius, coords, hp, hxy) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Index of current observation + INTEGER(c_int), INTENT(in) :: iobs_all + ! State dimension + INTEGER(c_int), INTENT(in) :: dim + ! Overall full observation dimension + INTEGER(c_int), INTENT(in) :: dim_obs + ! Types of localization function + INTEGER(c_int), DIMENSION(:), INTENT(in) :: locweights + ! Vector of localization cut-off radii + REAL(c_double), DIMENSION(:), INTENT(in) :: cradius + ! Vector of support radii of localization function + REAL(c_double), DIMENSION(:), INTENT(in) :: sradius + ! Coordinates of state vector elements + REAL(c_double), DIMENSION(:,:), INTENT(in) :: coords + ! Vector HP, dimension (dim) + REAL(c_double), DIMENSION(:), INTENT(inout) :: hp + ! Matrix HXY, dimension (nobs) + REAL(c_double), DIMENSION(:), INTENT(inout) :: hxy + + + call PDAFomi_localize_covar_serial_noniso_locweights(thisobs(i_obs), & + iobs_all, dim, dim_obs, locweights, cradius, sradius, coords, hp, hxy) + + END SUBROUTINE c__PDAFomi_localize_covar_serial_noniso_locweights + + SUBROUTINE c__PDAFomi_localize_covar_serial_noniso(i_obs, iobs_all, dim, dim_obs, & + locweight, cradius, sradius, coords, hp, hxy) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Index of current observation + INTEGER(c_int), INTENT(in) :: iobs_all + ! State dimension + INTEGER(c_int), INTENT(in) :: dim + ! Overall full observation dimension + INTEGER(c_int), INTENT(in) :: dim_obs + ! Localization weight type + INTEGER(c_int), INTENT(in) :: locweight + ! Vector of localization cut-off radii + REAL(c_double), DIMENSION(:), INTENT(in) :: cradius + ! Vector of support radii of localization function + REAL(c_double), DIMENSION(:), INTENT(in) :: sradius + ! Coordinates of state vector elements + REAL(c_double), DIMENSION(:,:), INTENT(in) :: coords + ! Vector HP, dimension (dim) + REAL(c_double), DIMENSION(:), INTENT(inout) :: hp + ! Matrix HXY, dimension (nobs) + REAL(c_double), DIMENSION(:), INTENT(inout) :: hxy + + + call PDAFomi_localize_covar_serial_noniso(thisobs(i_obs), iobs_all, dim, & + dim_obs, locweight, cradius, sradius, coords, hp, hxy) + + END SUBROUTINE c__PDAFomi_localize_covar_serial_noniso + + SUBROUTINE c__PDAFomi_init_dim_obs_l_iso_old(i_obs, coords_l, locweight, cradius, & + sradius, cnt_obs_l) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Coordinates of current analysis domain + REAL(c_double), DIMENSION(:), INTENT(in) :: coords_l + ! Type of localization function + INTEGER(c_int), INTENT(in) :: locweight + ! Localization cut-off radius (single or vector) + REAL(c_double), INTENT(in) :: cradius + ! Support radius of localization function (single or vector) + REAL(c_double), INTENT(in) :: sradius + ! Local dimension of current observation vector + INTEGER(c_int), INTENT(inout) :: cnt_obs_l + + + call PDAFomi_init_dim_obs_l_iso_old(thisobs_l(i_obs), thisobs(i_obs), & + coords_l, locweight, cradius, sradius, cnt_obs_l) + + END SUBROUTINE c__PDAFomi_init_dim_obs_l_iso_old + + SUBROUTINE c__PDAFomi_init_dim_obs_l_noniso_old(i_obs, coords_l, locweight, & + cradius, sradius, cnt_obs_l) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Coordinates of current analysis domain + REAL(c_double), DIMENSION(:), INTENT(in) :: coords_l + ! Type of localization function + INTEGER(c_int), INTENT(in) :: locweight + ! Vector of localization cut-off radii + REAL(c_double), DIMENSION(:), INTENT(in) :: cradius + ! Vector of support radii of localization function + REAL(c_double), DIMENSION(:), INTENT(in) :: sradius + ! Local dimension of current observation vector + INTEGER(c_int), INTENT(inout) :: cnt_obs_l + + + call PDAFomi_init_dim_obs_l_noniso_old(thisobs_l(i_obs), thisobs(i_obs), & + coords_l, locweight, cradius, sradius, cnt_obs_l) + + END SUBROUTINE c__PDAFomi_init_dim_obs_l_noniso_old + + SUBROUTINE c__PDAFomi_init_dim_obs_l_noniso_locweights_old(i_obs, coords_l, & + locweights, cradius, sradius, cnt_obs_l) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Coordinates of current analysis domain + REAL(c_double), DIMENSION(:), INTENT(in) :: coords_l + ! Types of localization function + INTEGER(c_int), DIMENSION(:), INTENT(in) :: locweights + ! Vector of localization cut-off radii + REAL(c_double), DIMENSION(:), INTENT(in) :: cradius + ! Vector of support radii of localization function + REAL(c_double), DIMENSION(:), INTENT(in) :: sradius + ! Local dimension of current observation vector + INTEGER(c_int), INTENT(inout) :: cnt_obs_l + + + call PDAFomi_init_dim_obs_l_noniso_locweights_old(thisobs_l(i_obs), & + thisobs(i_obs), coords_l, locweights, cradius, sradius, cnt_obs_l) + + END SUBROUTINE c__PDAFomi_init_dim_obs_l_noniso_locweights_old + + SUBROUTINE c__PDAFomi_deallocate_obs(i_obs) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + + + call PDAFomi_deallocate_obs(thisobs(i_obs)) + + END SUBROUTINE c__PDAFomi_deallocate_obs +end module pdafomi_c_legacy diff --git a/pyPDAF/source/src/fortran/pdafomi_c_put.f90 b/pyPDAF/source/src/fortran/pdafomi_c_put.f90 new file mode 100644 index 0000000000000000000000000000000000000000..a149b78cc87a49dd19e99547cbf3d65b6f46d0f6 --- /dev/null +++ b/pyPDAF/source/src/fortran/pdafomi_c_put.f90 @@ -0,0 +1,990 @@ +MODULE pdafomi_c_put +use iso_c_binding, only: c_int, c_double, c_bool +use PDAF +use pdaf_c_cb_interface +use pdaf_c_f_interface + +implicit none + +contains + SUBROUTINE c__PDAFomi_put_state_local_nondiagR(collect_state_pdaf, & + init_dim_obs_pdafomi, obs_op_pdafomi, prepoststep_pdaf, & + init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdafomi, & + prodrinva_l_pdafomi, g2l_state_pdaf, l2g_state_pdaf, outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdafomi + ! Provide product of inverse of R with matrix A + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdafomi + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: g2l_state_pdaf + ! Init full state from local state + procedure(c__l2g_state_pdaf) :: l2g_state_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdafomi + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdafomi + g2l_state_pdaf_c_ptr => g2l_state_pdaf + l2g_state_pdaf_c_ptr => l2g_state_pdaf + + call PDAFomi_put_state_local_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prepoststep_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__prodrinva_l_pdaf, f__g2l_state_pdaf, f__l2g_state_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_put_state_local_nondiagR + + SUBROUTINE c__PDAFomi_put_state_global_nondiagR(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, prodrinva_pdaf, prepoststep_pdaf, & + outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prodrinva_pdaf_c_ptr => prodrinva_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAFomi_put_state_global_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_put_state_global_nondiagR + + SUBROUTINE c__PDAFomi_put_state_enkf_nondiagR(collect_state_pdaf, & + init_dim_obs_pdafomi, obs_op_pdafomi, add_obs_error_pdafomi, & + init_obscovar_pdafomi, prepoststep_pdaf, outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! Add observation error covariance matrix + procedure(c__add_obs_err_pdaf) :: add_obs_error_pdafomi + ! Initialize mean observation error variance + procedure(c__init_obs_covar_pdaf) :: init_obscovar_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + add_obs_err_pdaf_c_ptr => add_obs_error_pdafomi + init_obs_covar_pdaf_c_ptr => init_obscovar_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAFomi_put_state_enkf_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__add_obs_err_pdaf, & + f__init_obs_covar_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_put_state_enkf_nondiagR + + SUBROUTINE c__PDAFomi_put_state_lenkf_nondiagR(collect_state_pdaf, & + init_dim_obs_pdafomi, obs_op_pdafomi, prepoststep_pdaf, & + localize_covar_pdafomi, add_obs_error_pdafomi, init_obscovar_pdafomi, & + outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Apply localization to HP and HPH^T + procedure(c__localize_covar_pdaf) :: localize_covar_pdafomi + ! Provide product R^-1 A + procedure(c__add_obs_err_pdaf) :: add_obs_error_pdafomi + ! Initialize mean observation error variance + procedure(c__init_obs_covar_pdaf) :: init_obscovar_pdafomi + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + localize_covar_pdaf_c_ptr => localize_covar_pdafomi + add_obs_err_pdaf_c_ptr => add_obs_error_pdafomi + init_obs_covar_pdaf_c_ptr => init_obscovar_pdafomi + + call PDAFomi_put_state_lenkf_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prepoststep_pdaf, & + f__localize_covar_pdaf, f__add_obs_err_pdaf, f__init_obs_covar_pdaf, & + outflag) + + END SUBROUTINE c__PDAFomi_put_state_lenkf_nondiagR + + SUBROUTINE c__PDAFomi_put_state_nonlin_nondiagR(collect_state_pdaf, & + init_dim_obs_pdafomi, obs_op_pdafomi, likelihood_pdafomi, & + prepoststep_pdaf, outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! Compute likelihood + procedure(c__likelihood_pdaf) :: likelihood_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + likelihood_pdaf_c_ptr => likelihood_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAFomi_put_state_nonlin_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__likelihood_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_put_state_nonlin_nondiagR + + SUBROUTINE c__PDAFomi_put_state_lnetf_nondiagR(collect_state_pdaf, & + init_dim_obs_pdafomi, obs_op_pdafomi, prepoststep_pdaf, & + init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdafomi, & + likelihood_l_pdafomi, g2l_state_pdaf, l2g_state_pdaf, outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdafomi + ! Compute likelihood and apply localization + procedure(c__likelihood_l_pdaf) :: likelihood_l_pdafomi + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: g2l_state_pdaf + ! Init full state from local state + procedure(c__l2g_state_pdaf) :: l2g_state_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdafomi + likelihood_l_pdaf_c_ptr => likelihood_l_pdafomi + g2l_state_pdaf_c_ptr => g2l_state_pdaf + l2g_state_pdaf_c_ptr => l2g_state_pdaf + + call PDAFomi_put_state_lnetf_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prepoststep_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__likelihood_l_pdaf, f__g2l_state_pdaf, f__l2g_state_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_put_state_lnetf_nondiagR + + SUBROUTINE c__PDAFomi_put_state_lknetf_nondiagR(collect_state_pdaf, & + init_dim_obs_pdafomi, obs_op_pdafomi, prepoststep_pdaf, & + init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdafomi, & + prodrinva_l_pdafomi, prodrinva_hyb_l_pdafomi, likelihood_l_pdafomi, & + likelihood_hyb_l_pdafomi, g2l_state_pdaf, l2g_state_pdaf, outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdafomi + ! Provide product R^-1 A on local analysis domain + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdafomi + ! Product R^-1 A on local analysis domain with hybrid weight + procedure(c__prodrinva_hyb_l_pdaf) :: prodrinva_hyb_l_pdafomi + ! Compute likelihood and apply localization + procedure(c__likelihood_l_pdaf) :: likelihood_l_pdafomi + ! Compute likelihood and apply localization with tempering + procedure(c__likelihood_hyb_l_pdaf) :: likelihood_hyb_l_pdafomi + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: g2l_state_pdaf + ! Init full state from local state + procedure(c__l2g_state_pdaf) :: l2g_state_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdafomi + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdafomi + prodrinva_hyb_l_pdaf_c_ptr => prodrinva_hyb_l_pdafomi + likelihood_l_pdaf_c_ptr => likelihood_l_pdafomi + likelihood_hyb_l_pdaf_c_ptr => likelihood_hyb_l_pdafomi + g2l_state_pdaf_c_ptr => g2l_state_pdaf + l2g_state_pdaf_c_ptr => l2g_state_pdaf + + call PDAFomi_put_state_lknetf_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prepoststep_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__prodrinva_l_pdaf, f__prodrinva_hyb_l_pdaf, f__likelihood_l_pdaf, & + f__likelihood_hyb_l_pdaf, f__g2l_state_pdaf, f__l2g_state_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_put_state_lknetf_nondiagR + + SUBROUTINE c__PDAFomi_put_state_3dvar(collect_state_pdaf, init_dim_obs_pdaf, & + obs_op_pdaf, cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, & + prepoststep_pdaf, outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAFomi_put_state_3dvar(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_put_state_3dvar + + SUBROUTINE c__PDAFomi_put_state_en3dvar_estkf(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, cvt_ens_pdaf, cvt_adj_ens_pdaf, & + obs_op_lin_pdaf, obs_op_adj_pdaf, prepoststep_pdaf, outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAFomi_put_state_en3dvar_estkf(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_put_state_en3dvar_estkf + + SUBROUTINE c__PDAFomi_put_state_en3dvar_lestkf(collect_state_pdaf, & + init_dim_obs_f_pdaf, obs_op_f_pdaf, cvt_ens_pdaf, cvt_adj_ens_pdaf, & + obs_op_lin_pdaf, obs_op_adj_pdaf, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdaf, g2l_state_pdaf, l2g_state_pdaf, prepoststep_pdaf, & + outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_f_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_f_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: g2l_state_pdaf + ! Init full state from local state + procedure(c__l2g_state_pdaf) :: l2g_state_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_f_pdaf_c_ptr => init_dim_obs_f_pdaf + obs_op_f_pdaf_c_ptr => obs_op_f_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + g2l_state_pdaf_c_ptr => g2l_state_pdaf + l2g_state_pdaf_c_ptr => l2g_state_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAFomi_put_state_en3dvar_lestkf(f__collect_state_pdaf, & + f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, & + f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, f__l2g_state_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_put_state_en3dvar_lestkf + + SUBROUTINE c__PDAFomi_put_state_hyb3dvar_estkf(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, cvt_ens_pdaf, cvt_adj_ens_pdaf, cvt_pdaf, & + cvt_adj_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, prepoststep_pdaf, & + outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply ensemble control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint ensemble control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAFomi_put_state_hyb3dvar_estkf(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, & + f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_put_state_hyb3dvar_estkf + + SUBROUTINE c__PDAFomi_put_state_hyb3dvar_lestkf(collect_state_pdaf, & + init_dim_obs_f_pdaf, obs_op_f_pdaf, cvt_ens_pdaf, cvt_adj_ens_pdaf, & + cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdaf, obs_op_adj_pdaf, & + init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdaf, & + g2l_state_pdaf, l2g_state_pdaf, prepoststep_pdaf, outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_f_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_f_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdaf + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: g2l_state_pdaf + ! Init full state from local state + procedure(c__l2g_state_pdaf) :: l2g_state_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_f_pdaf_c_ptr => init_dim_obs_f_pdaf + obs_op_f_pdaf_c_ptr => obs_op_f_pdaf + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdaf + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + g2l_state_pdaf_c_ptr => g2l_state_pdaf + l2g_state_pdaf_c_ptr => l2g_state_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAFomi_put_state_hyb3dvar_lestkf(f__collect_state_pdaf, & + f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, f__cvt_ens_pdaf, f__cvt_adj_ens_pdaf, & + f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, & + f__g2l_state_pdaf, f__l2g_state_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_put_state_hyb3dvar_lestkf + + SUBROUTINE c__PDAFomi_put_state_3dvar_nondiagR(collect_state_pdaf, & + init_dim_obs_pdafomi, obs_op_pdafomi, prodrinva_pdafomi, cvt_pdaf, & + cvt_adj_pdaf, obs_op_lin_pdafomi, obs_op_adj_pdafomi, prepoststep_pdaf, & + outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdafomi + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdafomi + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prodrinva_pdaf_c_ptr => prodrinva_pdafomi + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdafomi + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAFomi_put_state_3dvar_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, f__cvt_pdaf, & + f__cvt_adj_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_put_state_3dvar_nondiagR + + SUBROUTINE c__PDAFomi_put_state_en3dvar_estkf_nondiagR(collect_state_pdaf, & + init_dim_obs_pdafomi, obs_op_pdafomi, prodrinva_pdafomi, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, obs_op_lin_pdafomi, obs_op_adj_pdafomi, & + prepoststep_pdaf, outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdafomi + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdafomi + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prodrinva_pdaf_c_ptr => prodrinva_pdafomi + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdafomi + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAFomi_put_state_en3dvar_estkf_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_put_state_en3dvar_estkf_nondiagR + + SUBROUTINE c__PDAFomi_put_state_en3dvar_lestkf_nondiagR(collect_state_pdaf, & + init_dim_obs_pdafomi, obs_op_pdafomi, prodrinva_pdafomi, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, obs_op_lin_pdafomi, obs_op_adj_pdafomi, & + prodrinva_l_pdafomi, init_n_domains_pdaf, init_dim_l_pdaf, & + init_dim_obs_l_pdafomi, g2l_state_pdaf, l2g_state_pdaf, prepoststep_pdaf, & + outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdafomi + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdafomi + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdafomi + ! Provide product R^-1 A + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdafomi + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdafomi + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: g2l_state_pdaf + ! Init full state from local state + procedure(c__l2g_state_pdaf) :: l2g_state_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prodrinva_pdaf_c_ptr => prodrinva_pdafomi + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdafomi + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdafomi + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdafomi + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdafomi + g2l_state_pdaf_c_ptr => g2l_state_pdaf + l2g_state_pdaf_c_ptr => l2g_state_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAFomi_put_state_en3dvar_lestkf_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__obs_op_lin_pdaf, f__obs_op_adj_pdaf, & + f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, f__l2g_state_pdaf, & + f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_put_state_en3dvar_lestkf_nondiagR + + SUBROUTINE c__PDAFomi_put_state_hyb3dvar_estkf_nondiagR(collect_state_pdaf, & + init_dim_obs_pdafomi, obs_op_pdafomi, prodrinva_pdafomi, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdafomi, & + obs_op_adj_pdafomi, prepoststep_pdaf, outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdafomi + ! Apply ensemble control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint ensemble control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdafomi + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdafomi + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prodrinva_pdaf_c_ptr => prodrinva_pdafomi + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdafomi + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdafomi + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAFomi_put_state_hyb3dvar_estkf_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_put_state_hyb3dvar_estkf_nondiagR + + SUBROUTINE c__PDAFomi_put_state_hyb3dvar_lestkf_nondiagR(collect_state_pdaf, & + init_dim_obs_pdafomi, obs_op_pdafomi, prodrinva_pdafomi, cvt_ens_pdaf, & + cvt_adj_ens_pdaf, cvt_pdaf, cvt_adj_pdaf, obs_op_lin_pdafomi, & + obs_op_adj_pdafomi, prodrinva_l_pdafomi, init_n_domains_pdaf, & + init_dim_l_pdaf, init_dim_obs_l_pdafomi, g2l_state_pdaf, l2g_state_pdaf, & + prepoststep_pdaf, outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdafomi + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdafomi + ! Provide product R^-1 A + procedure(c__prodrinva_pdaf) :: prodrinva_pdafomi + ! Apply control vector transform matrix to control vector + procedure(c__cvt_ens_pdaf) :: cvt_ens_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_ens_pdaf) :: cvt_adj_ens_pdaf + ! Apply control vector transform matrix to control vector + procedure(c__cvt_pdaf) :: cvt_pdaf + ! Apply adjoint control vector transform matrix + procedure(c__cvt_adj_pdaf) :: cvt_adj_pdaf + ! Linearized observation operator + procedure(c__obs_op_pdaf) :: obs_op_lin_pdafomi + ! Adjoint observation operator + procedure(c__obs_op_adj_pdaf) :: obs_op_adj_pdafomi + ! Provide product R^-1 A + procedure(c__prodrinva_l_pdaf) :: prodrinva_l_pdafomi + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdafomi + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: g2l_state_pdaf + ! Init full state from local state + procedure(c__l2g_state_pdaf) :: l2g_state_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdafomi + obs_op_pdaf_c_ptr => obs_op_pdafomi + prodrinva_pdaf_c_ptr => prodrinva_pdafomi + cvt_ens_pdaf_c_ptr => cvt_ens_pdaf + cvt_adj_ens_pdaf_c_ptr => cvt_adj_ens_pdaf + cvt_pdaf_c_ptr => cvt_pdaf + cvt_adj_pdaf_c_ptr => cvt_adj_pdaf + obs_op_lin_pdaf_c_ptr => obs_op_lin_pdafomi + obs_op_adj_pdaf_c_ptr => obs_op_adj_pdafomi + prodrinva_l_pdaf_c_ptr => prodrinva_l_pdafomi + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdafomi + g2l_state_pdaf_c_ptr => g2l_state_pdaf + l2g_state_pdaf_c_ptr => l2g_state_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAFomi_put_state_hyb3dvar_lestkf_nondiagR(f__collect_state_pdaf, & + f__init_dim_obs_pdaf, f__obs_op_pdaf, f__prodrinva_pdaf, f__cvt_ens_pdaf, & + f__cvt_adj_ens_pdaf, f__cvt_pdaf, f__cvt_adj_pdaf, f__obs_op_lin_pdaf, & + f__obs_op_adj_pdaf, f__prodrinva_l_pdaf, f__init_n_domains_p_pdaf, & + f__init_dim_l_pdaf, f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, & + f__l2g_state_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_put_state_hyb3dvar_lestkf_nondiagR + + SUBROUTINE c__PDAFomi_put_state_local(collect_state_pdaf, & + init_dim_obs_f_pdaf, obs_op_f_pdaf, prepoststep_pdaf, & + init_n_domains_pdaf, init_dim_l_pdaf, init_dim_obs_l_pdaf, & + g2l_state_pdaf, l2g_state_pdaf, outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of full observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_f_pdaf + ! Full observation operator + procedure(c__obs_op_pdaf) :: obs_op_f_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Provide number of local analysis domains + procedure(c__init_n_domains_p_pdaf) :: init_n_domains_pdaf + ! Init state dimension for local ana. domain + procedure(c__init_dim_l_pdaf) :: init_dim_l_pdaf + ! Initialize local dimimension of obs. vector + procedure(c__init_dim_obs_l_pdaf) :: init_dim_obs_l_pdaf + ! Get state on local ana. domain from full state + procedure(c__g2l_state_pdaf) :: g2l_state_pdaf + ! Init full state from local state + procedure(c__l2g_state_pdaf) :: l2g_state_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_f_pdaf_c_ptr => init_dim_obs_f_pdaf + obs_op_f_pdaf_c_ptr => obs_op_f_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + init_n_domains_p_pdaf_c_ptr => init_n_domains_pdaf + init_dim_l_pdaf_c_ptr => init_dim_l_pdaf + init_dim_obs_l_pdaf_c_ptr => init_dim_obs_l_pdaf + g2l_state_pdaf_c_ptr => g2l_state_pdaf + l2g_state_pdaf_c_ptr => l2g_state_pdaf + + call PDAFomi_put_state_local(f__collect_state_pdaf, f__init_dim_obs_f_pdaf, & + f__obs_op_f_pdaf, f__prepoststep_pdaf, f__init_n_domains_p_pdaf, f__init_dim_l_pdaf, & + f__init_dim_obs_l_pdaf, f__g2l_state_pdaf, f__l2g_state_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_put_state_local + + SUBROUTINE c__PDAFomi_put_state_global(collect_state_pdaf, & + init_dim_obs_pdaf, obs_op_pdaf, prepoststep_pdaf, outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(inout) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAFomi_put_state_global(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_put_state_global + + SUBROUTINE c__PDAFomi_put_state_lenkf(collect_state_pdaf, init_dim_obs_pdaf, & + obs_op_pdaf, prepoststep_pdaf, localize_covar_pdaf, outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + ! Apply localization to HP and HPH^T + procedure(c__localize_covar_pdaf) :: localize_covar_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + localize_covar_pdaf_c_ptr => localize_covar_pdaf + + call PDAFomi_put_state_lenkf(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__prepoststep_pdaf, f__localize_covar_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_put_state_lenkf + + SUBROUTINE c__PDAFomi_put_state_ensrf(collect_state_pdaf, init_dim_obs_pdaf, & + obs_op_pdaf, localize_covar_serial_pdaf, prepoststep_pdaf, outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_pdaf + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_pdaf + ! Apply localization to HP and HXY + procedure(c__localize_covar_serial_pdaf) :: localize_covar_serial_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_pdaf_c_ptr => init_dim_obs_pdaf + obs_op_pdaf_c_ptr => obs_op_pdaf + localize_covar_serial_pdaf_c_ptr => localize_covar_serial_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAFomi_put_state_ensrf(f__collect_state_pdaf, f__init_dim_obs_pdaf, & + f__obs_op_pdaf, f__localize_covar_serial_pdaf, f__prepoststep_pdaf, outflag) + + END SUBROUTINE c__PDAFomi_put_state_ensrf + + SUBROUTINE c__PDAFomi_put_state_generate_obs(collect_state_pdaf, & + init_dim_obs_f_pdaf, obs_op_f_pdaf, get_obs_f_pdaf, prepoststep_pdaf, & + outflag) bind(c) + use iso_c_binding + + ! Status flag + INTEGER(c_int), INTENT(out) :: outflag + + ! Routine to collect a state vector + procedure(c__collect_state_pdaf) :: collect_state_pdaf + ! Initialize dimension of observation vector + procedure(c__init_dim_obs_pdaf) :: init_dim_obs_f_pdaf + ! Observation operator + procedure(c__obs_op_pdaf) :: obs_op_f_pdaf + ! Initialize observation vector + procedure(c__get_obs_f_pdaf) :: get_obs_f_pdaf + ! User supplied pre/poststep routine + procedure(c__prepoststep_pdaf) :: prepoststep_pdaf + + collect_state_pdaf_c_ptr => collect_state_pdaf + init_dim_obs_f_pdaf_c_ptr => init_dim_obs_f_pdaf + obs_op_f_pdaf_c_ptr => obs_op_f_pdaf + get_obs_f_pdaf_c_ptr => get_obs_f_pdaf + prepoststep_pdaf_c_ptr => prepoststep_pdaf + + call PDAFomi_put_state_generate_obs(f__collect_state_pdaf, & + f__init_dim_obs_f_pdaf, f__obs_op_f_pdaf, f__get_obs_f_pdaf, f__prepoststep_pdaf, & + outflag) + + END SUBROUTINE c__PDAFomi_put_state_generate_obs +END MODULE pdafomi_c_put diff --git a/pyPDAF/source/src/fortran/pdafomi_c_setter.f90 b/pyPDAF/source/src/fortran/pdafomi_c_setter.f90 new file mode 100644 index 0000000000000000000000000000000000000000..86bd5e5680583dc2d6815a96dda0f884a9f329c6 --- /dev/null +++ b/pyPDAF/source/src/fortran/pdafomi_c_setter.f90 @@ -0,0 +1,163 @@ +MODULE pdafomi_c_setter +use iso_c_binding, only: c_int, c_double, c_bool, c_null_char, c_char +use PDAF +use pdaf_c_cb_interface +use pdafomi_c, only: n_obs_omi, thisobs, thisobs_l +implicit none + +contains + SUBROUTINE c__PDAFomi_set_doassim(i_obs, doassim) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Flag whether to assimilate this observation type + INTEGER(c_int), INTENT(in) :: doassim + + + call PDAFomi_set_doassim(thisobs(i_obs), doassim) + + END SUBROUTINE c__PDAFomi_set_doassim + + SUBROUTINE c__PDAFomi_set_disttype(i_obs, disttype) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Index of distance type + INTEGER(c_int), INTENT(in) :: disttype + + + call PDAFomi_set_disttype(thisobs(i_obs), disttype) + + END SUBROUTINE c__PDAFomi_set_disttype + + SUBROUTINE c__PDAFomi_set_ncoord(i_obs, ncoord) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Number of coordinates + INTEGER(c_int), INTENT(in) :: ncoord + + + call PDAFomi_set_ncoord(thisobs(i_obs), ncoord) + + END SUBROUTINE c__PDAFomi_set_ncoord + + SUBROUTINE c__PDAFomi_set_obs_err_type(i_obs, obs_err_type) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Type of observation error + INTEGER(c_int), INTENT(in) :: obs_err_type + + + call PDAFomi_set_obs_err_type(thisobs(i_obs), obs_err_type) + + END SUBROUTINE c__PDAFomi_set_obs_err_type + + SUBROUTINE c__PDAFomi_set_use_global_obs(i_obs, use_global_obs) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Set whether to use global full observations + INTEGER(c_int), INTENT(in) :: use_global_obs + + + call PDAFomi_set_use_global_obs(thisobs(i_obs), use_global_obs) + + END SUBROUTINE c__PDAFomi_set_use_global_obs + + SUBROUTINE c__PDAFomi_set_inno_omit(i_obs, inno_omit) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Set observation omission error variance level + REAL(c_double), INTENT(in) :: inno_omit + + + call PDAFomi_set_inno_omit(thisobs(i_obs), inno_omit) + + END SUBROUTINE c__PDAFomi_set_inno_omit + + SUBROUTINE c__PDAFomi_set_inno_omit_ivar(i_obs, inno_omit_ivar) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! Value of inverse variance to omit observation + REAL(c_double), INTENT(in) :: inno_omit_ivar + + + call PDAFomi_set_inno_omit_ivar(thisobs(i_obs), inno_omit_ivar) + + END SUBROUTINE c__PDAFomi_set_inno_omit_ivar + + SUBROUTINE c__PDAFomi_set_id_obs_p(i_obs, nrows, dim_obs_p, id_obs_p) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! number of rows required in observation operator + INTEGER(c_int), INTENT(in) :: nrows + ! number of process local observations + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Indices of process-local observed field in state vector + INTEGER(c_int), DIMENSION(nrows, dim_obs_p), INTENT(in) :: id_obs_p + + + call PDAFomi_set_id_obs_p(thisobs(i_obs), nrows, dim_obs_p, id_obs_p) + + END SUBROUTINE c__PDAFomi_set_id_obs_p + + SUBROUTINE c__PDAFomi_set_icoeff_p(i_obs, nrows, dim_obs_p, icoeff_p) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! number of rows required in observation operator + INTEGER(c_int), INTENT(in) :: nrows + ! number of process local observations + INTEGER(c_int), INTENT(in) :: dim_obs_p + ! Interpolation coeffs. for obs. operator + REAL(c_double), DIMENSION(nrows, dim_obs_p), INTENT(in) :: icoeff_p + + + call PDAFomi_set_icoeff_p(thisobs(i_obs), nrows, dim_obs_p, icoeff_p) + + END SUBROUTINE c__PDAFomi_set_icoeff_p + + SUBROUTINE c__PDAFomi_set_domainsize(i_obs, ncoord, domainsize) bind(c) + ! index into observation arrays + INTEGER(c_int), INTENT(in) :: i_obs + + ! number of coordinates considered for localizations + INTEGER(c_int), INTENT(in) :: ncoord + ! Size of domain for periodicity (<=0 for no periodicity) + REAL(c_double), DIMENSION(ncoord), INTENT(in) :: domainsize + + + call PDAFomi_set_domainsize(thisobs(i_obs), ncoord, domainsize) + + END SUBROUTINE c__PDAFomi_set_domainsize + + SUBROUTINE c__PDAFomi_set_name(i_obs, obsname) bind(c) + use PDAFOMI_obs_f, only: PDAFomi_set_name + IMPLICIT NONE + !< Data type with full observation + INTEGER(c_int), INTENT(inout) :: i_obs + !< Name of observation type + CHARACTER(kind=c_char), dimension(*), INTENT(in) :: obsname + + CHARACTER(len=20) :: clean_obsname + INTEGER :: i + + ! Remove null characters from filterstr + clean_obsname = "" + i = 1 + DO WHILE (.true.) + IF (obsname(i) == c_null_char) EXIT + clean_obsname(i:i) = obsname(i) + i = i + 1 + END DO + + call PDAFomi_set_name(thisobs(i_obs), clean_obsname) + + END SUBROUTINE c__PDAFomi_set_name + +END MODULE pdafomi_c_setter diff --git a/pyPDAF/source/src/pyPDAF/PDAF/__init__.py b/pyPDAF/source/src/pyPDAF/PDAF/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b3876f1c8cc0b8cb4d1b17e8a36b79df12dfdcba --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/__init__.py @@ -0,0 +1,31 @@ +"""Namespace for pyPDAF.PDAF package +""" +from ._pdaf_c import correlation_function, deallocate, eofcovar, \ + force_analysis, gather_dim_obs_f, gather_obs_f, \ + gather_obs_f2, gather_obs_f_flex, \ + gather_obs_f2_flex, init, init_forecast, \ + local_weight, local_weights, print_filter_types, \ + print_da_types, print_info, reset_forget, sample_ens, \ + get_fcst_info +from .setter import set_comm_pdaf, set_debug_flag, set_ens_pointer, \ + set_iparam, set_memberid, set_offline_mode, \ + set_rparam, set_seedset, set_smoother_ens +from .get import get_assim_flag, get_localfilter, \ + get_local_type, get_memberid, get_obsmemberid, \ + get_smoother_ens +from .iau import iau_init, iau_reset, iau_set_pointer +from .diag import diag_ensmean, \ + diag_stddev_nompi, \ + diag_stddev, \ + diag_variance_nompi, \ + diag_variance, \ + diag_rmsd_nompi, \ + diag_rmsd, \ + diag_crps_mpi, \ + diag_crps_nompi, \ + diag_effsample, \ + diag_ensstats, \ + diag_compute_moments, \ + diag_histogram, \ + diag_reliability_budget +from .assim import get_state diff --git a/pyPDAF/source/src/pyPDAF/PDAF/_pdaf_c.pxd b/pyPDAF/source/src/pyPDAF/PDAF/_pdaf_c.pxd new file mode 100644 index 0000000000000000000000000000000000000000..50348b5bc449576c11d85f3d7e99831c62381386 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/_pdaf_c.pxd @@ -0,0 +1,74 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t + +cdef extern void c__pdaf_get_fcst_info(int* steps, double* time, + int* doexit) noexcept nogil; + +cdef extern void c__pdaf_correlation_function(int* ctype, double* length, + double* distance, double* value) noexcept nogil; + +cdef extern void c__pdaf_deallocate() noexcept nogil; + +cdef extern void c__pdaf_eofcovar(int* dim, int* nstates, int* nfields, + int* dim_fields, int* offsets, int* remove_mstate, int* do_mv, + double* states, double* stddev, double* svals, double* svec, + double* meanstate, int* verbose, + int* status) noexcept nogil; + +cdef extern void c__pdaf_force_analysis() noexcept nogil; + +cdef extern void c__pdaf_gather_dim_obs_f(int* dim_obs_p, + int* dim_obs_f) noexcept nogil; + +cdef extern void c__pdaf_gather_obs_f(double* obs_p, double* obs_f, + int* status) noexcept nogil; + +cdef extern void c__pdaf_gather_obs_f2(double* coords_p, double* coords_f, + int* nrows, int* status) noexcept nogil; + +cdef extern void c__pdaf_gather_obs_f_flex(int* dim_obs_p, int* dim_obs_f, + double* obs_p, double* obs_f, int* status) noexcept nogil; + +cdef extern void c__pdaf_gather_obs_f2_flex(int* dim_obs_p, int* dim_obs_f, + double* coords_p, double* coords_f, int* nrows, + int* status) noexcept nogil; + +cdef extern void c__pdaf_init(int* filtertype, int* subtype, int* stepnull, + int* param_int, int* dim_pint, double* param_real, int* dim_preal, + int* comm_model, int* comm_filter, int* comm_couple, int* task_id, + int* n_modeltasks, bint* in_filterpe, + void (*c__init_ens_pdaf)(int* , int* , int* , double* , double* , + double* , int* ), + int* in_screen, int* outflag) noexcept nogil; + +cdef extern void c__pdaf_init_forecast( + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_local_weight(int* wtype, int* rtype, + double* cradius, double* sradius, double* distance, int* nrows, + int* ncols, double* a, double* var_obs, double* weight, + int* verbose) noexcept nogil; + +cdef extern void c__pdaf_local_weights(int* wtype, double* cradius, + double* sradius, int* dim, double* distance, double* weight, + int* verbose) noexcept nogil; + +cdef extern void c__pdaf_print_filter_types( + int* verbose) noexcept nogil; + +cdef extern void c__pdaf_print_da_types( + int* verbose) noexcept nogil; + +cdef extern void c__pdaf_print_info( + int* printtype) noexcept nogil; + +cdef extern void c__pdaf_reset_forget( + double* forget_in) noexcept nogil; + +cdef extern void c__pdaf_sampleens(int* dim, int* dim_ens, double* modes, + double* svals, double* state, double* ens, int* verbose, + int* flag) noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/PDAF/_pdaf_c.pyi b/pyPDAF/source/src/pyPDAF/PDAF/_pdaf_c.pyi new file mode 100644 index 0000000000000000000000000000000000000000..23990e91a04719f226a946249e1155f48da70b36 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/_pdaf_c.pyi @@ -0,0 +1,807 @@ +# pylint: disable=unused-argument +from typing import Tuple, Callable, Any +import numpy as np +from numpy.typing import NDArray + +def get_fcst_info(steps: int, time : float, doexit:int) -> Tuple[int, float, int]: + """Return the number of time steps, current model time, and a flag + whether the forecasting should be exited. + + This is used when the flexible parallelization mode is used with + :func:`pyPDAF.PDAF3.assimilate`. This is also relevant for the + legacy assimilation functions. + + See also `relevant PDAF page `_. + + Parameters + ---------- + steps : int + number of forecast time steps for next assimilation + The input value can be an arbitrary integer + time : float + current model time + doexit : int + Whether to exit from forecasts + + Returns + ------- + steps : int + number of forecast time steps for next assimilation + The input value can be an arbitrary integer + time : float + current model time + doexit : int + Whether to exit from forecasts + """ + +def correlation_function(ctype: int, length: float, distance: float) -> float: + """The value of the chosen correlation function according to the specified + length scale. + + Parameters + ---------- + ctype : int + Type of correlation function + * ctype=1: Gaussian with f(0)=1.0 + * ctype=2: 5th-order polynomial (Gaspace/Cohn, 1999) + length : float + Length scale of function + * ctype=1: standard deviation + * ctype=2: support length f=0 for distance>length + distance : float + Distance at which the function is evaluated + + Returns + ------- + value : float + Value of the function + """ + + +def deallocate() -> None: + """Finalise the PDAF systems including freeing some of the memory used by PDAF. + + This function cannot be used to free all allocated PDAF memory. + Therefore, one should not use :func:`pyPDAF.PDAF.init` afterwards. + """ + + +def eofcovar( + dim: int, + nstates: int, + nfields: int, + dim_fields: NDArray[np.int32], + offsets: NDArray[np.int32], + remove_mstate: int, + do_mv: int, + states: NDArray[np.float64], + meanstate: NDArray[np.float64], + verbose: int, +) -> Tuple[ + NDArray[np.float64], # states + NDArray[np.float64], # stddev + NDArray[np.float64], # svals + NDArray[np.float64], # svec + NDArray[np.float64], # meanstate + int, # status +]: + """ + EOF analysis of an ensemble of state vectors by singular value decomposition. + + Typically, this function is used with :func:`pyPDAF.PDAF.SampleEns` + to generate an ensemble of a chosen size (up to the number of EOFs plus one). + + Here, the function performs a singular value decomposition + of the ensemble anomaly of the input matrix, + which is usually an ensemble formed by state vectors + at multiple time steps. + The singular values and corresponding singular vectors + can be used to construct a covariance matrix. + This can be used as the initial error covariance for the initial ensemble. + + A multivariate scaling can be performed to ensure that all fields + in the state vectors have unit variance. + + It can be useful to store more EOFs than one finally + might want to use to have the flexibility + to carry the ensemble size. + + + See Also + -------- + `PDAF webpage `_ + + Parameters + ---------- + dim : int + Dimension of state vector + nstates : int + Number of state vectors + nfields : int + Number of fields in state vector + dim_fields : ndarray[np.intc, ndim=1] + Size of each field + Array shape: (nfields) + offsets : ndarray[np.intc, ndim=1] + Start position of each field + Array shape: (nfields) + remove_mstate : int + 1: subtract mean state from states + do_mv : int + 1: Do multivariate scaling; 0: no scaling + states : ndarray[np.float64, ndim=2] + State perturbations + Array shape: (dim, nstates) + meanstate : ndarray[np.float64, ndim=1] + Mean state (only changed if remove_mstate=1) + Array shape: (dim) + verbose : int + Verbosity flag + + Returns + ------- + states : ndarray[np.float64, ndim=2] + State perturbations + Array shape: (dim, nstates) + stddev : ndarray[np.float64, ndim=1] + Standard deviation of field variability + Array shape: (nfields) + svals : ndarray[np.float64, ndim=1] + Singular values divided by sqrt(nstates-1) + Array shape: (nstates) + svec : ndarray[np.float64, ndim=2] + Singular vectors + Array shape: (dim, nstates) + meanstate : ndarray[np.float64, ndim=1] + Mean state (only changed if remove_mstate=1) + Array shape: (dim) + status : int + Status flag + """ + + +def force_analysis() -> None: + """Perform assimilation after this function call. + + This function overwrite member index of the ensemble state + by local_dim_ens (number of ensembles for current process, + in full parallel setup, this is 1.) and the counter + cnt_steps by nsteps-1. + This forces that the analysis step is executed at + the next call to PDAF assimilation functions. + """ + + +def gather_dim_obs_f(dim_obs_p: int) -> int: + """Gather the dimension of observation vector + across multiple local domains/filter processors. + + This function is typically used in deprecated PDAF functions + without OMI. + + This function can be used in the user-supplied function of + :func:`py__init_dim_obs_f_pdaf`, + but it is recommended to use :func:`pyPDAF.PDAF.omi_gather_obs` + with OMI. + + This function does two things: + 1. Receiving observation dimension on each local process. + 2. Gather the total dimension of observation + across local process and the displacement of PE-local + observations relative to the total observation vector + + The dimension of observations are used to allocate observation + arrays. Therefore, it must be used before + :func:`pyPDAF.PDAF.gather_obs_f` or :func:`pyPDAF.PDAF.gather_obs_f2`. + + Parameters + ---------- + dim_obs_p : int + PE-local observation dimension + + Returns + ------- + dim_obs_f : int + Full observation dimension + """ + + +def gather_obs_f( + obs_p: NDArray[np.float64], + dimobs_f: int, +) -> Tuple[NDArray[np.float64], int]: + """In the local filters (LESKTF, LETKF, LSEIK, LNETF) this function + returns the total observation vector from process-local observations. + The function depends on :func:`pyPDAF.PDAF.gather_dim_obs_f` which defines + the process-local observation dimensions. Further, + the related routine :func:`pyPDAF.PDAF.gather_obs_f2` is used to + gather the associated 2D observation coordinates + + Parameters + ---------- + obs_p : ndarray[np.float64, ndim=1] + PE-local vector + Array shape: (dimobs_p) + dimobs_f : int + Full observation dimension, dimension of `obs_f` + + Returns + ------- + obs_f : ndarray[np.float64, ndim=1] + Full gathered vector + Array shape: (dimobs_f) + status : int + Status flag: + """ + + +def gather_obs_f2( + coords_p: NDArray[np.float64], + nrows: int, + dimobs_f: int, +) -> Tuple[NDArray[np.float64], int]: + """In the local filters (LESKTF, LETKF, LSEIK, LNETF) + this function returns the full observation coordinates from process-local + observation coordinates. The function depends on + func:`pyPDAF.PDAF.gather_dim_obs_f` which defines the process-local + observation dimensions. Further, the related routine + func:`pyPDAF.PDAF.gather_obs_f` is used to gather the associated + observation vectors. + + The routine is typically used in the routines `py__init_dim_obs_f_pdaf` + if the analysis step of the local filters is parallelized. + + Parameters + ---------- + coords_p : ndarray[np.float64, ndim=2] + PE-local array + Array shape: (nrows, dimobs_p) + nrows : int + Number of rows in array + dimobs_f : int + Full observation dimension, dimension of `coords_f` + + Returns + ------- + coords_f : ndarray[np.float64, ndim=2] + Full gathered array + Array shape: (nrows, dimobs_f) + status : int + Status flag: + """ + + +def gather_obs_f_flex( + dim_obs_p: int, + dim_obs_f: int, + obs_p: NDArray[np.float64], +) -> Tuple[NDArray[np.float64], int]: + """Gather full observation from processor + local observation without PDAF-internal info. + + In the local filters (LESKTF, LETKF, LSEIK, LNETF) + this function returns the full observation + from process-local observation. + + This function has a similar functionality as + :func:`pyPDAF.PDAF.gather_obs_f`, but it does not depend + on PDAF-internal observation dimension information, + which is specified once :func:`pyPDAF.PDAF.gather_dim_obs_f` + is executed. + + This function can also be used as a generic function + to gather any 2D arrays + where the second dimension should be concatenated. + + Parameters + ---------- + dim_obs_p : int + PE-local observation dimension + dim_obs_f : int + Full observation dimension + obs_p : ndarray[np.float64, ndim=1] + PE-local vector + Array shape: (dim_obs_p) + + Returns + ------- + obs_f : ndarray[np.float64, ndim=1] + Full gathered vector + Array shape: (dim_obs_f) + status : int + Status flag: (0) no error + """ + + +def gather_obs_f2_flex( + dim_obs_p: int, + dim_obs_f: int, + coords_p: NDArray[np.float64], + nrows: int, +) -> Tuple[NDArray[np.float64], int]: + """Gather full observation coordinates from processor + local observation coordinates without PDAF-internal info. + + In the local filters (LESKTF, LETKF, LSEIK, LNETF) + this function returns the full observation coordinates + from process-local observation coordinates. + + This function has a similar functionality as + :func:`pyPDAF.PDAF.gather_obs_f2`, but it does not depend + on PDAF-internal observation dimension information, + which is specified once :func:`pyPDAF.PDAF.gather_dim_obs_f` + is executed. + + This function can also be used as a generic function + to gather any 2D arrays + where the second dimension should be concatenated. + + Parameters + ---------- + dim_obs_p : int + PE-local observation dimension + dim_obs_f : int + Full observation dimension + coords_p : ndarray[np.float64, ndim=2] + PE-local array + Array shape: (nrows, dim_obs_p) + nrows : int + Number of rows in array + + Returns + ------- + coords_f : ndarray[np.float64, ndim=2] + Full gathered array + Array shape: (nrows, dim_obs_f) + status : int + Status flag: (0) no error + """ + + +def init( + filtertype: int, + subtype: int, + stepnull: int, + param_int: NDArray[np.int32], + dim_pint: int, + param_real: NDArray[np.float64], + dim_preal: int, + comm_model: int, + comm_filter: int, + comm_couple: int, + task_id: int, + n_modeltasks: int, + in_filterpe: bool, + py__init_ens_pdaf: Callable[..., Any], + in_screen: int, +) -> Tuple[NDArray[np.int32], NDArray[np.float64], int]: + """Initialise the PDAF system. + + It is called once at the beginning of the assimilation. + + The function specifies the type of DA methods, + parameters of the filters, the MPI communicators, + and other parallel options. + The filter options including `filtertype`, `subtype`, + `param_int`, and `param_real` + are introduced in + `PDAF filter options wiki page `_. + Note that the size of `param_int` and `param_real` depends on + the filter type and subtype. However, for most filters, + they require at least the state vector size and ensemble size + for `param_int`, and the forgetting factor for `param_real`. + + The MPI communicators asked by this function depends on + the parallelisation strategy. + For the default parallelisation strategy, the user + can use the parallelisation module + provided under in `example directory `_ + without modifications. + The parallelisation can differ based on online and offline cases. + Users can also refer to `parallelisation documentation `_ for + explanations or modifications. + + This function also asks for a user-supplied function + :func:`py__init_ens_pdaf`. + This function is designed to provides an initial ensemble + to the internal PDAF ensemble array. + The internal PDAF ensemble then can be distributed to + initialise the model forecast using + :func:`pyPDAF.PDAF.get_state`. + This user-supplied function can be empty if the model + has already read the ensemble from restart files. + + Parameters + ---------- + filtertype : int + Type of filter + subtype : int + Sub-type of filter + stepnull : int + Initial time step of assimilation + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + dim_pint : int + Number of integer parameters + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + dim_preal : int + Number of real parameter + comm_model : int + Model communicator + comm_filter : int + Filter communicator + comm_couple : int + Coupling communicator + task_id : int + Id of my ensemble task + n_modeltasks : int + Number of parallel model tasks + in_filterpe : bint + Is my PE a filter-PE? + py__init_ens_pdaf : Callable + Initialise ensemble array in PDAF + in_screen : int + Control screen output: + + Returns + ------- + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + outflag : int + Status flag, 0: no error, error codes: + """ + + +def init_forecast( + py__next_observation_pdaf: Callable[..., Any], + py__distribute_state_pdaf: Callable[..., Any], + py__prepoststep_pdaf: Callable[..., Any], + outflag: int, +) -> int: + """The routine PDAF_init_forecast has to be called once at the end of the + initialization of PDAF/start of DA cycles. + + This function has the purpose to initialize the model fields to be + propagated from the array holding the ensemble states. In addition, + the function initializes the information on how many time steps have to be + performed in the upcoming forecast phase before the next assimilation step, + and an exit flag indicating whether further model integrations have to be computed. + These variables are used internally in PDAF and can be retrieved by + the user by calling PDAF_get_fcst_info. + + Parameters + ---------- + py__next_observation_pdaf : Callable + Get the number of time steps to be computed in the forecast phase. + See details for :func:`pyPDAF.pdaf_c_cb_interface.c__next_observation_pdaf`. + py__distribute_state_pdaf : Callable + Distribute a state vector from pdaf to the model/any arrays + See details for :func:`pyPDAF.pdaf_c_cb_interface.c__distribute_state_pdaf`. + py__prepoststep_pdaf : Callable + Process ensemble before or after DA. + See details for :func:`pyPDAF.pdaf_c_cb_interface.c__prepoststep_pdaf`. + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + + +def local_weight( + wtype: int, + rtype: int, + cradius: float, + sradius: float, + distance: float, + nrows: int, + ncols: int, + a: NDArray[np.float64], + var_obs: float, + verbose: int, +) -> float: + """Get localisation weight for given distance, + cut-off radius, support radius, weighting type, + and weighting function. + + This function is used in the analysis step of a filter + to computes a localisation weight. + + Typically, in domain-localised filters, the function + is called in user-supplied :func:`py__prodRinvA_l_pdaf`. + In LEnKF, this function is called + in user-supplied :func:`py__localize_covar_pdaf`. + + This function is usually only used without PDAF-OMI. + + Parameters + ---------- + wtype : int + type of weight function: + * `wtype=0`: unit weight + (`weight=1` up to distance=cradius) + * `wtype=1`: exponential decrease + (`weight=1/e` at distance=sradius; + `weight=0` for distance>cradius) + * `wtype=2`: 5th order polynomial + (Gaspari and Cohn 1999; `weight=0` for distance>cradius) + rtype : int + type of regulated weighting: + * `rtype/=1`: no regulation + * `rtype=1`: regulated by variance of the matrix A and + the observation variance + cradius : float + cut-off radius where weight = 0 beyond the cradius + sradius : float + support radius of localisation function. This depends on `wtype`: + * `wtype=0`: sradius is not used + * `wtype=1`: weight = :math:`e^{-\\frac{distance}{sradius}}` + * `wtype=2`: weight = 0 if distance > sradius + else weight = f(distance ,sradius) + + See also: `PDAF-OMI wiki `_ + distance : float + distance to observation + nrows : int + Number of rows in matrix A + ncols : int + Number of columns in matrix A + a : ndarray[tuple[nrows, ncols, ...], np.float64] + ensemble perturbation/anomaly matrix; + this matrix is used when weighting is regulated + by mean variance, i.e., rtype = 1. + Array shape: (nrows, ncols) + var_obs : double + Observation variance + verbose : int + Verbosity flag + + Returns + ------- + weight : double + localisation weights + """ + + +def local_weights( + wtype: int, + cradius: float, + sradius: float, + dim: int, + distance: NDArray[np.float64], + verbose: int, +) -> NDArray[np.float64]: + """Get a vector of localisation weights for given distances, + cut-off radius, support radius, weighting type, + and weighting function. + + This function is used in the analysis step of a filter + to computes a localisation weight. + + Typically, in domain-localised filters, the function + is called in user-supplied :func:`py__prodRinvA_l_pdaf`. + In LEnKF, this function is called + in user-supplied :func:`py__localize_covar_pdaf`. + + This function is usually only used without PDAF-OMI. + + This function is a vectorised version of + :func:`pyPDAF.PDAF.local_weight` without any regulations. + + Parameters + ---------- + wtype : int + type of weight function: + * `wtype=0`: unit weight + (`weight=1` up to distance=cradius) + * `wtype=1`: exponential decrease + (`weight=1/e` at distance=sradius; + `weight=0` for distance>cradius) + * `wtype=2`: 5th order polynomial + (Gaspari and Cohn 1999; `weight=0` for distance>cradius) + rtype : int + type of regulated weighting: + * `rtype/=1`: no regulation + * `rtype=1`: regulated by variance of the matrix A and + the observation variance + cradius : float + cut-off radius where weight = 0 beyond the cradius + sradius : float + support radius of localisation function. This depends on `wtype`: + * `wtype=0`: sradius is not used + * `wtype=1`: weight = :math:`e^{-\\frac{distance}{sradius}}` + * `wtype=2`: weight = 0 if distance > sradius + else weight = f(distance ,sradius) + dim : int + Size of distance and weight arrays + distance : ndarray[np.float64, ndim=1] + distance to observation + Array shape: (dim) + verbose : int + Verbosity flag + + Returns + ------- + weight : ndarray[np.float64, ndim=1] + Array for localisation weights + Array shape: (dim) + """ + + +def print_filter_types(verbose: int) -> None: + """Print the list of available named DA method types and their IDs. + + Wrapper of the Fortran routine ``PDAF_print_DA_types(verbose)``. If + ``verbose > 0``, it writes to stdout the names and corresponding integer + identifiers of supported data assimilation method types (same list as + for filters). This helps when specifying method types by integer or by + named parameter. + + The printed names include: + - PDAF_DA_LESTKF + - PDAF_DA_ESTKF + - PDAF_DA_LETKF + - PDAF_DA_ETKF + - PDAF_DA_LENKF + - PDAF_DA_ENKF + - PDAF_DA_LSEIK + - PDAF_DA_SEIK + - PDAF_DA_ENSRF + - PDAF_DA_LNETF + - PDAF_DA_NETF + - PDAF_DA_PF + - PDAF_DA_LKNETF + - PDAF_DA_GENOBS + - PDAF_DA_3DVAR + + Parameters + ---------- + verbose : int + Verbosity flag. If 0, no output is printed; if > 0, the list is + printed to stdout. + + Returns + ------- + None + """ + + +def print_da_types(verbose: int) -> None: + """Print PDAF timing and memory information. + + Wrapper of the Fortran routine ``PDAF_print_info(printtype)``. Prints + aggregated timing information and/or memory usage depending on + ``printtype``. Call this near the end of your DA program. + + Parameters + ---------- + printtype : int + Type of screen output: + - 1: general timings + - 3: timers focused on call-back routines (recommended) + - 4: detailed timers (analyze filters) + - 5: very detailed timers (deep filter analysis) + - 10: allocated memory of the calling MPI task + - 11: globally used memory (call from all processes) + """ + + +def print_info(printtype: int) -> None: + """Print PDAF timing and memory information. + + Wrapper of the Fortran routine ``PDAF_print_info(printtype)``. Prints + aggregated timing information and/or memory usage depending on + ``printtype``. Call this near the end of your DA program. + + Parameters + ---------- + printtype : int + Type of information to be printed + * printtype=1: Basic timers + * printtype=3: Timers showing the time spent in the different call-back routines + (this variant was added with PDAF 1.15) + * printtype=4: More detailed timers about parts of the filter algorithm + (before PDAF 1.15, this was timer level 3) + * printtype=5: Very detailed timers about various operations in the filter algorithm + (before PDAF 1.15, this was timer level 4) + * printtype=10: Memory usage (The value 10 is valid since PDAF V2.1. For older versions use 2) + + - Memory required for the ensemble array, + state vector, and transform matrix + - Memory required by the analysis step + - Memory required to perform the ensemble transformation + """ + + +def reset_forget(forget_in: float) -> None: + """Reset the forgetting factor manually + during the assimilation process. + + For the local ensemble Kalman filters + the forgetting factor can be set either globally + if this function is called outside of the loop over + local domains, + or + the forgetting factor can be set differently + for each local analysis domain within the loop over + local domains. + + For the LNETF and the global filters + only a global setting of the forgeting factor is possible. + In addition, the implementation of adaptive choices + for the forgetting factor (beyond what is implemented in PDAF) are possible. + + Parameters + ---------- + forget_in : double + New value of forgetting factor + + """ + + +def sample_ens( + dim: int, + dim_ens: int, + modes: NDArray[np.float64], + svals: NDArray[np.float64], + state: NDArray[np.float64], + verbose: int, + flag: int, +) -> Tuple[ + NDArray[np.float64], # modes + NDArray[np.float64], # state + NDArray[np.float64], # ens + int, # flag +]: + r"""Generate an ensemble from singular values and + their vectors (EOF modes) of an ensemble anomaly matrix. + + The singular values and vectors are derived from + the ensemble anomalies. This ensemble anomaly can be + obtained from a time anomaly of a model trajectory using + :func:`pyPDAF.PDAF.eofcovar`. + + Parameters + ---------- + dim: int + Size of the state vector + dim_ens : int + Ensemble size + modes : ndarray[tuple[dim, dim_ens-1, ...], np.float64] + array of EOF modes/matrix of singular vectors. + svals : ndarray[tuple[dim_ens-1, ...], np.float64] + singular values. + state : ndarray[tuple[dim, ...], np.float64] + PE-local model mean state. + verbose : int + Verbosity flag + flag : int + Status flag + + Returns + ------- + modes : ndarray[tuple[dim, dim_ens-1, ...], np.float64] + array of EOF modes/matrix of singular vectors + + The 1st-th dimension dim is size of state vector + state : ndarray[tuple[dim, ...], np.float64] + PE-local model mean state + + The array dimension `dim` is size of state vector + ens : ndarray[tuple[dim, dim_ens, ...], np.float64] + State ensemble + + The 1st-th dimension dim is size of state vector + The 2nd-th dimension dim_ens is size of ensemble + flag : int + Status flag + """ diff --git a/pyPDAF/source/src/pyPDAF/PDAF/_pdaf_c.pyx b/pyPDAF/source/src/pyPDAF/PDAF/_pdaf_c.pyx new file mode 100644 index 0000000000000000000000000000000000000000..01b0d5de266521c7880d2dc781757a799acc6285 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/_pdaf_c.pyx @@ -0,0 +1,907 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + + +def get_fcst_info(int steps, double time, int doexit): + """get_fcst_info(steps: int, time : float, doexit:int) -> Tuple[int, float, int] + + Return the number of time steps, current model time, and a flag + whether the forecasting should be exited. + + This is used when the flexible parallelization mode is used with + :func:`pyPDAF.PDAF3.assimilate`. This is also relevant for the + legacy assimilation functions. + + See also `relevant PDAF page `_. + + Parameters + ---------- + steps : int + number of forecast time steps for next assimilation + The input value can be an arbitrary integer + time : float + current model time + doexit : int + Whether to exit from forecasts + + Returns + ------- + steps : int + number of forecast time steps for next assimilation + The input value can be an arbitrary integer + time : float + current model time + doexit : int + Whether to exit from forecasts + """ + with nogil: + c__pdaf_get_fcst_info(&steps, &time, &doexit) + + return steps, time, doexit + + +def correlation_function(int ctype, double length, double distance): + """correlation_function(ctype: int, length: float, distance: float) -> float + + The value of the chosen correlation function according to the specified + length scale. + + Parameters + ---------- + ctype : int + Type of correlation function + * ctype=1: Gaussian with f(0)=1.0 + * ctype=2: 5th-order polynomial (Gaspace/Cohn, 1999) + length : double + Length scale of function + * ctype=1: standard deviation + * ctype=2: support length f=0 for distance>length + distance : double + Distance at which the function is evaluated + + Returns + ------- + value : double + Value of the function + """ + cdef double value + with nogil: + c__pdaf_correlation_function(&ctype, &length, &distance, &value) + + return value + + +def deallocate(): + """deallocate() -> None + + Finalise the PDAF systems including freeing some of the memory used by PDAF. + + This function cannot be used to free all allocated PDAF memory. + Therefore, one should not use :func:`pyPDAF.PDAF.init` afterwards. + """ + with nogil: + c__pdaf_deallocate() + + +def eofcovar(int dim, int nstates, int nfields, int [::1] dim_fields, + int [::1] offsets, int remove_mstate, int do_mv, + double [::1,:] states, double [::1] meanstate, int verbose): + """eofcovar(dim: int, nstates: int, nfields: int, dim_fields: ndarray[np.intc, ndim=1], offsets: ndarray[np.intc, ndim=1], remove_mstate: int, do_mv: int, states: ndarray[np.float64, ndim=2], meanstate: ndarray[np.float64, ndim=1], verbose: int) -> Tuple[ndarray[np.float64, ndim=2], ndarray[np.float64, ndim=1], ndarray[np.float64, ndim=1], ndarray[np.float64, ndim=2], ndarray[np.float64, ndim=1], int] + + EOF analysis of an ensemble of state vectors by singular value decomposition. + + Typically, this function is used with :func:`pyPDAF.PDAF.SampleEns` + to generate an ensemble of a chosen size (up to the number of EOFs plus one). + + Here, the function performs a singular value decomposition + of the ensemble anomaly of the input matrix, + which is usually an ensemble formed by state vectors + at multiple time steps. + The singular values and corresponding singular vectors + can be used to construct a covariance matrix. + This can be used as the initial error covariance for the initial ensemble. + + A multivariate scaling can be performed to ensure that all fields + in the state vectors have unit variance. + + It can be useful to store more EOFs than one finally + might want to use to have the flexibility + to carry the ensemble size. + + + See Also + -------- + `PDAF webpage `_ + + Parameters + ---------- + dim : int + Dimension of state vector + nstates : int + Number of state vectors + nfields : int + Number of fields in state vector + dim_fields : ndarray[np.intc, ndim=1] + Size of each field + Array shape: (nfields) + offsets : ndarray[np.intc, ndim=1] + Start position of each field + Array shape: (nfields) + remove_mstate : int + 1: subtract mean state from states + do_mv : int + 1: Do multivariate scaling; 0: no scaling + states : ndarray[np.float64, ndim=2] + State perturbations + Array shape: (dim, nstates) + meanstate : ndarray[np.float64, ndim=1] + Mean state (only changed if remove_mstate=1) + Array shape: (dim) + verbose : int + Verbosity flag + + Returns + ------- + states : ndarray[np.float64, ndim=2] + State perturbations + Array shape: (dim, nstates) + stddev : ndarray[np.float64, ndim=1] + Standard deviation of field variability + Array shape: (nfields) + svals : ndarray[np.float64, ndim=1] + Singular values divided by sqrt(nstates-1) + Array shape: (nstates) + svec : ndarray[np.float64, ndim=2] + Singular vectors + Array shape: (dim, nstates) + meanstate : ndarray[np.float64, ndim=1] + Mean state (only changed if remove_mstate=1) + Array shape: (dim) + status : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] states_np = np.asarray(states, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] stddev_np = np.zeros((nfields), dtype=np.float64, order="F") + cdef double [::1] stddev = stddev_np + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] svals_np = np.zeros((nstates), dtype=np.float64, order="F") + cdef double [::1] svals = svals_np + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] svec_np = np.zeros((dim, nstates), dtype=np.float64, order="F") + cdef double [::1,:] svec = svec_np + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] meanstate_np = np.asarray(meanstate, dtype=np.float64, order="F") + cdef int status + with nogil: + c__pdaf_eofcovar(&dim, &nstates, &nfields, &dim_fields[0], + &offsets[0], &remove_mstate, &do_mv, &states[0,0], + &stddev[0], &svals[0], &svec[0,0], &meanstate[0], + &verbose, &status) + + return states_np, stddev_np, svals_np, svec_np, meanstate_np, status + + +def force_analysis(): + """force_analysis() -> None + + Perform assimilation after this function call. + + This function overwrite member index of the ensemble state + by local_dim_ens (number of ensembles for current process, + in full parallel setup, this is 1.) and the counter + cnt_steps by nsteps-1. + This forces that the analysis step is executed at + the next call to PDAF assimilation functions. + """ + with nogil: + c__pdaf_force_analysis() + + + +def gather_dim_obs_f(int dim_obs_p): + """gather_dim_obs_f(dim_obs_p:int) -> int + + Gather the dimension of observation vector + across multiple local domains/filter processors. + + This function is typically used in deprecated PDAF functions + without OMI. + + This function can be used in the user-supplied function of + :func:`py__init_dim_obs_f_pdaf`, + but it is recommended to use :func:`pyPDAF.PDAF.omi_gather_obs` + with OMI. + + This function does two things: + 1. Receiving observation dimension on each local process. + 2. Gather the total dimension of observation + across local process and the displacement of PE-local + observations relative to the total observation vector + + The dimension of observations are used to allocate observation + arrays. Therefore, it must be used before + :func:`pyPDAF.PDAF.gather_obs_f` or :func:`pyPDAF.PDAF.gather_obs_f2`. + + Parameters + ---------- + dim_obs_p : int + PE-local observation dimension + + Returns + ------- + dim_obs_f : int + Full observation dimension + """ + cdef int dim_obs_f + with nogil: + c__pdaf_gather_dim_obs_f(&dim_obs_p, &dim_obs_f) + + return dim_obs_f + + +def gather_obs_f(double [::1] obs_p, int dimobs_f): + """gather_obs_f(obs_p: NDArray[np.float64], dimobs_f: int) -> Tuple[NDArray[np.float64], int] + + In the local filters (LESKTF, LETKF, LSEIK, LNETF) this function + returns the total observation vector from process-local observations. + The function depends on :func:`pyPDAF.PDAF.gather_dim_obs_f` which defines + the process-local observation dimensions. Further, + the related routine :func:`pyPDAF.PDAF.gather_obs_f2` is used to + gather the associated 2D observation coordinates + + Parameters + ---------- + obs_p : ndarray[np.float64, ndim=1] + PE-local vector + Array shape: (dimobs_p) + dimobs_f : int + Full observation dimension, dimension of `obs_f` + + Returns + ------- + obs_f : ndarray[np.float64, ndim=1] + Full gathered vector + Array shape: (dimobs_f) + status : int + Status flag: + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obs_f_np = np.zeros((dimobs_f), dtype=np.float64, order="F") + cdef double [::1] obs_f = obs_f_np + cdef int status + with nogil: + c__pdaf_gather_obs_f(&obs_p[0], &obs_f[0], &status) + + return obs_f_np, status + + +def gather_obs_f2(double [::1,:] coords_p, int nrows, int dimobs_f): + """gather_obs_f2(coords_p: NDArray[np.float64], nrows: int, dimobs_f: int) -> Tuple[NDArray[np.float64], int] + + In the local filters (LESKTF, LETKF, LSEIK, LNETF) + this function returns the full observation coordinates from process-local + observation coordinates. The function depends on + func:`pyPDAF.PDAF.gather_dim_obs_f` which defines the process-local + observation dimensions. Further, the related routine + func:`pyPDAF.PDAF.gather_obs_f` is used to gather the associated + observation vectors. + + The routine is typically used in the routines `py__init_dim_obs_f_pdaf` + if the analysis step of the local filters is parallelized. + + Parameters + ---------- + coords_p : ndarray[np.float64, ndim=2] + PE-local array + Array shape: (nrows, dimobs_p) + nrows : int + Number of rows in array + dimobs_f : int + Full observation dimension, dimension of `coords_f` + + Returns + ------- + coords_f : ndarray[np.float64, ndim=2] + Full gathered array + Array shape: (nrows, dimobs_f) + status : int + Status flag: + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] coords_f_np = np.zeros((nrows, dimobs_f), dtype=np.float64, order="F") + cdef double [::1,:] coords_f = coords_f_np + cdef int status + with nogil: + c__pdaf_gather_obs_f2(&coords_p[0,0], &coords_f[0,0], &nrows, &status) + + return coords_f_np, status + + +def gather_obs_f_flex(int dim_obs_p, int dim_obs_f, double [::1] obs_p): + """gather_obs_f_flex(dim_obs_p: int, dim_obs_f: int, obs_p: NDArray[np.float64]) -> Tuple[NDArray[np.float64], int] + + Gather full observation from processor + local observation without PDAF-internal info. + + In the local filters (LESKTF, LETKF, LSEIK, LNETF) + this function returns the full observation + from process-local observation. + + This function has a similar functionality as + :func:`pyPDAF.PDAF.gather_obs_f`, but it does not depend + on PDAF-internal observation dimension information, + which is specified once :func:`pyPDAF.PDAF.gather_dim_obs_f` + is executed. + + This function can also be used as a generic function + to gather any 2D arrays + where the second dimension should be concatenated. + + Parameters + ---------- + dim_obs_p : int + PE-local observation dimension + dim_obs_f : int + Full observation dimension + obs_p : ndarray[np.float64, ndim=1] + PE-local vector + Array shape: (dim_obs_p) + + Returns + ------- + obs_f : ndarray[np.float64, ndim=1] + Full gathered vector + Array shape: (dim_obs_f) + status : int + Status flag: (0) no error + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obs_f_np = np.zeros((dim_obs_f), dtype=np.float64, order="F") + cdef double [::1] obs_f = obs_f_np + cdef int status + with nogil: + c__pdaf_gather_obs_f_flex(&dim_obs_p, &dim_obs_f, &obs_p[0], + &obs_f[0], &status) + + return obs_f_np, status + + +def gather_obs_f2_flex(int dim_obs_p, int dim_obs_f, + double [::1,:] coords_p, int nrows): + """gather_obs_f2_flex(dim_obs_p: int, dim_obs_f: int, coords_p: NDArray[np.float64], nrows: int) -> Tuple[NDArray[np.float64], int] + + Gather full observation coordinates from processor + local observation coordinates without PDAF-internal info. + + In the local filters (LESKTF, LETKF, LSEIK, LNETF) + this function returns the full observation coordinates + from process-local observation coordinates. + + This function has a similar functionality as + :func:`pyPDAF.PDAF.gather_obs_f2`, but it does not depend + on PDAF-internal observation dimension information, + which is specified once :func:`pyPDAF.PDAF.gather_dim_obs_f` + is executed. + + This function can also be used as a generic function + to gather any 2D arrays + where the second dimension should be concatenated. + + Parameters + ---------- + dim_obs_p : int + PE-local observation dimension + dim_obs_f : int + Full observation dimension + coords_p : ndarray[np.float64, ndim=2] + PE-local array + Array shape: (nrows, dim_obs_p) + nrows : int + Number of rows in array + + Returns + ------- + coords_f : ndarray[np.float64, ndim=2] + Full gathered array + Array shape: (nrows, dim_obs_f) + status : int + Status flag: (0) no error + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] coords_f_np = np.zeros((nrows, dim_obs_f), dtype=np.float64, order="F") + cdef double [::1,:] coords_f = coords_f_np + cdef int status + with nogil: + c__pdaf_gather_obs_f2_flex(&dim_obs_p, &dim_obs_f, &coords_p[0,0], + &coords_f[0,0], &nrows, &status) + + return coords_f_np, status + + +def init(int filtertype, int subtype, int stepnull, int [::1] param_int, + int dim_pint, double [::1] param_real, int dim_preal, + int comm_model, int comm_filter, int comm_couple, int task_id, + int n_modeltasks, bint in_filterpe, py__init_ens_pdaf, int in_screen): + """init(filtertype: int, subtype: int, stepnull: int, param_int: NDArray[np.int32], dim_pint: int, param_real: NDArray[np.float64], dim_preal: int, comm_model: int, comm_filter: int, comm_couple: int, task_id: int, n_modeltasks: int, in_filterpe: bool, py__init_ens_pdaf: Callable[..., Any], in_screen: int) -> Tuple[NDArray[np.int32], NDArray[np.float64], int] + + Initialise the PDAF system. + + It is called once at the beginning of the assimilation. + + The function specifies the type of DA methods, + parameters of the filters, the MPI communicators, + and other parallel options. + The filter options including `filtertype`, `subtype`, + `param_int`, and `param_real` + are introduced in + `PDAF filter options wiki page `_. + Note that the size of `param_int` and `param_real` depends on + the filter type and subtype. However, for most filters, + they require at least the state vector size and ensemble size + for `param_int`, and the forgetting factor for `param_real`. + + The MPI communicators asked by this function depends on + the parallelisation strategy. + For the default parallelisation strategy, the user + can use the parallelisation module + provided under in `example directory `_ + without modifications. + The parallelisation can differ based on online and offline cases. + Users can also refer to `parallelisation documentation `_ for + explanations or modifications. + + This function also asks for a user-supplied function + :func:`py__init_ens_pdaf`. + This function is designed to provides an initial ensemble + to the internal PDAF ensemble array. + The internal PDAF ensemble then can be distributed to + initialise the model forecast using + :func:`pyPDAF.PDAF.get_state`. + This user-supplied function can be empty if the model + has already read the ensemble from restart files. + + Parameters + ---------- + filtertype : int + Type of filter + subtype : int + Sub-type of filter + stepnull : int + Initial time step of assimilation + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + dim_pint : int + Number of integer parameters + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + dim_preal : int + Number of real parameter + comm_model : int + Model communicator + comm_filter : int + Filter communicator + comm_couple : int + Coupling communicator + task_id : int + Id of my ensemble task + n_modeltasks : int + Number of parallel model tasks + in_filterpe : bint + Is my PE a filter-PE? + py__init_ens_pdaf : Callable + Initialise ensemble array in PDAF + in_screen : int + Control screen output: + + Returns + ------- + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + outflag : int + Status flag, 0: no error, error codes: + """ + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_int_np = np.asarray(param_int, dtype=np.intc, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_real_np = np.asarray(param_real, dtype=np.float64, order="F") + pdaf_cb.init_ens_pdaf = py__init_ens_pdaf + cdef int outflag + with nogil: + c__pdaf_init(&filtertype, &subtype, &stepnull, ¶m_int[0], + &dim_pint, ¶m_real[0], &dim_preal, &comm_model, + &comm_filter, &comm_couple, &task_id, &n_modeltasks, + &in_filterpe, pdaf_cb.c__init_ens_pdaf, &in_screen, + &outflag) + + return param_int_np, param_real_np, outflag + + +def init_forecast(py__next_observation_pdaf, py__distribute_state_pdaf, + py__prepoststep_pdaf, int outflag): + """init_forecast(py__next_observation_pdaf: Callable[..., Any], py__distribute_state_pdaf: Callable[..., Any], py__prepoststep_pdaf: Callable[..., Any], outflag: int) -> int + + The routine PDAF_init_forecast has to be called once at the end of the + initialization of PDAF/start of DA cycles. + + This function has the purpose to initialize the model fields to be + propagated from the array holding the ensemble states. In addition, + the function initializes the information on how many time steps have to be + performed in the upcoming forecast phase before the next assimilation step, + and an exit flag indicating whether further model integrations have to be computed. + These variables are used internally in PDAF and can be retrieved by + the user by calling PDAF_get_fcst_info. + + Parameters + ---------- + py__next_observation_pdaf : Callable + Get the number of time steps to be computed in the forecast phase. + See details for :func:`pyPDAF.pdaf_c_cb_interface.c__next_observation_pdaf`. + py__distribute_state_pdaf : Callable + Distribute a state vector from pdaf to the model/any arrays + See details for :func:`pyPDAF.pdaf_c_cb_interface.c__distribute_state_pdaf`. + py__prepoststep_pdaf : Callable + Process ensemble before or after DA. + See details for :func:`pyPDAF.pdaf_c_cb_interface.c__prepoststep_pdaf`. + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + with nogil: + c__pdaf_init_forecast(pdaf_cb.c__next_observation_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def local_weight(int wtype, int rtype, double cradius, double sradius, + double distance, int nrows, int ncols, double [::1,:] a, + double var_obs, int verbose): + """local_weight(wtype: int, rtype: int, cradius: float, sradius: float, distance: float, nrows: int, ncols: int, a: NDArray[np.float64], var_obs: float, verbose: int) -> float + + Get localisation weight for given distance, + cut-off radius, support radius, weighting type, + and weighting function. + + This function is used in the analysis step of a filter + to computes a localisation weight. + + Typically, in domain-localised filters, the function + is called in user-supplied :func:`py__prodRinvA_l_pdaf`. + In LEnKF, this function is called + in user-supplied :func:`py__localize_covar_pdaf`. + + This function is usually only used without PDAF-OMI. + + Parameters + ---------- + wtype : int + type of weight function: + * `wtype=0`: unit weight + (`weight=1` up to distance=cradius) + * `wtype=1`: exponential decrease + (`weight=1/e` at distance=sradius; + `weight=0` for distance>cradius) + * `wtype=2`: 5th order polynomial + (Gaspari and Cohn 1999; `weight=0` for distance>cradius) + rtype : int + type of regulated weighting: + * `rtype/=1`: no regulation + * `rtype=1`: regulated by variance of the matrix A and + the observation variance + cradius : float + cut-off radius where weight = 0 beyond the cradius + sradius : float + support radius of localisation function. This depends on `wtype`: + * `wtype=0`: sradius is not used + * `wtype=1`: weight = :math:`e^{-\\frac{distance}{sradius}}` + * `wtype=2`: weight = 0 if distance > sradius + else weight = f(distance ,sradius) + + See also: `PDAF-OMI wiki `_ + distance : float + distance to observation + nrows : int + Number of rows in matrix A + ncols : int + Number of columns in matrix A + a : ndarray[tuple[nrows, ncols, ...], np.float64] + ensemble perturbation/anomaly matrix; + this matrix is used when weighting is regulated + by mean variance, i.e., rtype = 1. + Array shape: (nrows, ncols) + var_obs : double + Observation variance + verbose : int + Verbosity flag + + Returns + ------- + weight : double + localisation weights + """ + cdef double weight + with nogil: + c__pdaf_local_weight(&wtype, &rtype, &cradius, &sradius, &distance, + &nrows, &ncols, &a[0,0], &var_obs, &weight, + &verbose) + + return weight + + +def local_weights(int wtype, double cradius, double sradius, int dim, + double [::1] distance, int verbose): + """local_weights(wtype: int, cradius: float, sradius: float, dim: int, distance: NDArray[np.float64], verbose: int) -> NDArray[np.float64] + + Get a vector of localisation weights for given distances, + cut-off radius, support radius, weighting type, + and weighting function. + + This function is used in the analysis step of a filter + to computes a localisation weight. + + Typically, in domain-localised filters, the function + is called in user-supplied :func:`py__prodRinvA_l_pdaf`. + In LEnKF, this function is called + in user-supplied :func:`py__localize_covar_pdaf`. + + This function is usually only used without PDAF-OMI. + + This function is a vectorised version of + :func:`pyPDAF.PDAF.local_weight` without any regulations. + + Parameters + ---------- + wtype : int + type of weight function: + * `wtype=0`: unit weight + (`weight=1` up to distance=cradius) + * `wtype=1`: exponential decrease + (`weight=1/e` at distance=sradius; + `weight=0` for distance>cradius) + * `wtype=2`: 5th order polynomial + (Gaspari and Cohn 1999; `weight=0` for distance>cradius) + rtype : int + type of regulated weighting: + * `rtype/=1`: no regulation + * `rtype=1`: regulated by variance of the matrix A and + the observation variance + cradius : float + cut-off radius where weight = 0 beyond the cradius + sradius : float + support radius of localisation function. This depends on `wtype`: + * `wtype=0`: sradius is not used + * `wtype=1`: weight = :math:`e^{-\\frac{distance}{sradius}}` + * `wtype=2`: weight = 0 if distance > sradius + else weight = f(distance ,sradius) + dim : int + Size of distance and weight arrays + distance : ndarray[np.float64, ndim=1] + distance to observation + Array shape: (dim) + verbose : int + Verbosity flag + + Returns + ------- + weight : ndarray[np.float64, ndim=1] + Array for localisation weights + Array shape: (dim) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] weight_np = np.zeros((dim), dtype=np.float64, order="F") + cdef double [::1] weight = weight_np + with nogil: + c__pdaf_local_weights(&wtype, &cradius, &sradius, &dim, + &distance[0], &weight[0], &verbose) + + return weight_np + + +def print_filter_types(int verbose): + """print_filter_types(verbose: int) -> None + + Print the list of available named filter types and their IDs. + + This is a thin wrapper of the Fortran routine + ``PDAF_print_filter_types(verbose)``. If ``verbose > 0``, it writes to + stdout the names and corresponding integer identifiers of the supported + data assimilation filter types. This is useful to see which integer codes + can be passed as ``filtertype`` to :func:`pyPDAF.PDAF.init`. + + The printed list includes (names shown; the routine also prints their + numeric codes): + - PDAF_DA_LESTKF + - PDAF_DA_ESTKF + - PDAF_DA_LETKF + - PDAF_DA_ETKF + - PDAF_DA_LENKF + - PDAF_DA_ENKF + - PDAF_DA_LSEIK + - PDAF_DA_SEIK + - PDAF_DA_ENSRF + - PDAF_DA_LNETF + - PDAF_DA_NETF + - PDAF_DA_PF + - PDAF_DA_LKNETF + - PDAF_DA_GENOBS + - PDAF_DA_3DVAR + + Parameters + ---------- + verbose : int + Verbosity flag. If 0, no output is printed; if > 0, the list is + printed to stdout. + + Returns + ------- + None + """ + with nogil: + c__pdaf_print_filter_types(&verbose) + + + +def print_da_types(int verbose): + """print_da_types(verbose: int) -> None + + Print the list of available named DA method types and their IDs. + + Wrapper of the Fortran routine ``PDAF_print_DA_types(verbose)``. If + ``verbose > 0``, it writes to stdout the names and corresponding integer + identifiers of supported data assimilation method types (same list as + for filters). This helps when specifying method types by integer or by + named parameter. + + The printed names include: + - PDAF_DA_LESTKF + - PDAF_DA_ESTKF + - PDAF_DA_LETKF + - PDAF_DA_ETKF + - PDAF_DA_LENKF + - PDAF_DA_ENKF + - PDAF_DA_LSEIK + - PDAF_DA_SEIK + - PDAF_DA_ENSRF + - PDAF_DA_LNETF + - PDAF_DA_NETF + - PDAF_DA_PF + - PDAF_DA_LKNETF + - PDAF_DA_GENOBS + - PDAF_DA_3DVAR + + Parameters + ---------- + verbose : int + Verbosity flag. If 0, no output is printed; if > 0, the list is + printed to stdout. + + Returns + ------- + None + """ + with nogil: + c__pdaf_print_da_types(&verbose) + + + +def print_info(int printtype): + """print_info(printtype: int) -> None + + Print PDAF timing and memory information. + + Wrapper of the Fortran routine ``PDAF_print_info(printtype)``. Prints + aggregated timing information and/or memory usage depending on + ``printtype``. Call this near the end of your DA program. + + Parameters + ---------- + printtype : int + Type of screen output: + - 1: general timings + - 3: timers focused on call-back routines (recommended) + - 4: detailed timers (analyze filters) + - 5: very detailed timers (deep filter analysis) + - 10: allocated memory of the calling MPI task + - 11: globally used memory (call from all processes) + """ + with nogil: + c__pdaf_print_info(&printtype) + + + +def reset_forget(double forget_in): + """reset_forget(forget_in: float) -> None + + Reset the forgetting factor manually + during the assimilation process. + + For the local ensemble Kalman filters + the forgetting factor can be set either globally + if this function is called outside of the loop over + local domains, + or + the forgetting factor can be set differently + for each local analysis domain within the loop over + local domains. + + For the LNETF and the global filters + only a global setting of the forgeting factor is possible. + In addition, the implementation of adaptive choices + for the forgetting factor (beyond what is implemented in PDAF) are possible. + + Parameters + ---------- + forget_in : double + New value of forgetting factor + + """ + with nogil: + c__pdaf_reset_forget(&forget_in) + + + +def sample_ens(int dim, int dim_ens, double [::1,:] modes, + double [::1] svals, double [::1] state, int verbose, int flag): + r"""sample_ens(dim: int, dim_ens: int, modes: NDArray[np.float64], svals: NDArray[np.float64], state: NDArray[np.float64], verbose: int, flag: int) -> Tuple[NDArray[np.float64], NDArray[np.float64], NDArray[np.float64], int,] + + Generate an ensemble from singular values and + their vectors (EOF modes) of an ensemble anomaly matrix. + + The singular values and vectors are derived from + the ensemble anomalies. This ensemble anomaly can be + obtained from a time anomaly of a model trajectory using + :func:`pyPDAF.PDAF.eofcovar`. + + Parameters + ---------- + dim: int + Size of the state vector + dim_ens : int + Ensemble size + modes : ndarray[tuple[dim, dim_ens-1, ...], np.float64] + array of EOF modes/matrix of singular vectors. + svals : ndarray[tuple[dim_ens-1, ...], np.float64] + singular values. + state : ndarray[tuple[dim, ...], np.float64] + PE-local model mean state. + verbose : int + Verbosity flag + flag : int + Status flag + + Returns + ------- + modes : ndarray[tuple[dim, dim_ens-1, ...], np.float64] + array of EOF modes/matrix of singular vectors + + The 1st-th dimension dim is size of state vector + state : ndarray[tuple[dim, ...], np.float64] + PE-local model mean state + + The array dimension `dim` is size of state vector + ens : ndarray[tuple[dim, dim_ens, ...], np.float64] + State ensemble + + The 1st-th dimension dim is size of state vector + The 2nd-th dimension dim_ens is size of ensemble + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] modes_np = np.asarray(modes, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_np = np.asarray(state, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_np = np.zeros((dim, dim_ens), dtype=np.float64, order="F") + cdef double [::1,:] ens = ens_np + with nogil: + c__pdaf_sampleens(&dim, &dim_ens, &modes[0,0], &svals[0], + &state[0], &ens[0,0], &verbose, &flag) + + return modes_np, state_np, ens_np, flag diff --git a/pyPDAF/source/src/pyPDAF/PDAF/assim.pxd b/pyPDAF/source/src/pyPDAF/PDAF/assim.pxd new file mode 100644 index 0000000000000000000000000000000000000000..3f1851da5ab116dbe16c1b6293c95f89cd23a326 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/assim.pxd @@ -0,0 +1,723 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t +cdef extern void c__pdaf_get_state(int* steps, double* time, int* doexit, + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assimilate_estkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assim_offline_estkf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assimilate_3dvar( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assim_offline_3dvar( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assimilate_en3dvar_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_f_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assim_offline_en3dvar_lestkf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_f_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assimilate_ensrf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obsvars_pdaf)(int* , int* , double* ), + void (*c__localize_covar_serial_pdaf)(int* , int* , int* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assim_offline_ensrf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obsvars_pdaf)(int* , int* , double* ), + void (*c__localize_covar_serial_pdaf)(int* , int* , int* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assimilate_lknetf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__prodrinva_hyb_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__likelihood_hyb_l_pdaf)(int* , int* , int* , double* , + double* , double* , double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assim_offline_lknetf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__prodrinva_hyb_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__likelihood_hyb_l_pdaf)(int* , int* , int* , double* , + double* , double* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assimilate_hyb3dvar_estkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assim_offline_hyb3dvar_estkf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assimilate_hyb3dvar_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_f_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assim_offline_hyb3dvar_lestkf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_f_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assimilate_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assim_offline_lestkf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assimilate_enkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assim_offline_enkf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assimilate_letkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assim_offline_letkf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assimilate_seik( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assim_offline_seik( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assimilate_lnetf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assim_offline_lnetf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assimilate_prepost( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assimilate_en3dvar_estkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assim_offline_en3dvar_estkf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assimilate_netf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__likelihood_pdaf)(int* , int* , double* , double* , double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assim_offline_netf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__likelihood_pdaf)(int* , int* , double* , double* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assimilate_pf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__likelihood_pdaf)(int* , int* , double* , double* , double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assim_offline_pf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__likelihood_pdaf)(int* , int* , double* , double* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assimilate_lenkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__localize_covar_pdaf)(int* , int* , double* , double* ), + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assim_offline_lenkf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__localize_covar_pdaf)(int* , int* , double* , double* ), + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assimilate_etkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assim_offline_etkf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assimilate_lseik( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_assim_offline_lseik( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_generate_obs( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obserr_f_pdaf)(int* , int* , double* , double* ), + void (*c__get_obs_f_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_generate_obs_offline( + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obserr_f_pdaf)(int* , int* , double* , double* ), + void (*c__get_obs_f_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/PDAF/assim.pyi b/pyPDAF/source/src/pyPDAF/PDAF/assim.pyi new file mode 100644 index 0000000000000000000000000000000000000000..c0339bd1f6f07f3fa5af15f967627af12a9e4f3f --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/assim.pyi @@ -0,0 +1,67 @@ +from typing import Callable + +def get_state(steps:int, doexit:int, py__next_observation_pdaf:Callable, + py__distribute_state_pdaf:Callable, py__prepoststep_pdaf:Callable, + outflag:int) -> tuple[int, float, int, int]: + """Distribute analysis state vector to an array. + + The primary purpose of this function is to distribute + the analysis state vector to the model. + This is attained by the user-supplied function + :func:`py__distribute_state_pdaf`. + One can also use this function to get the state vector + for other purposes, e.g. to write the state vector to a file. + + In this function, the user-supplied function + :func:`py__next_observation_pdaf` is executed + to specify the number of forecast time steps + until the next assimilation step. + One can also use the user-supplied function to + end the assimilation. + + In an online DA system, this function also execute + the user-supplied function :func:`py__prepoststep_state_pdaf`, + when this function is first called. The purpose of this design + is to call this function right after :func:`pyPDAF.PDAF.init` + to process the initial ensemble before using it to + initialse model forecast. This user-supplied function + will not be called afterwards. + + This function is also used in flexible parallel system + where the number of ensemble members are greater than + the parallel model tasks. In this case, this function + is called multiple times to distribute the analysis ensemble. + + User-supplied function are executed in the following sequence: + + 1. py__prepoststep_state_pdaf + (only in online system when first called) + 2. py__distribute_state_pdaf + 3. py__next_observation_pdaf + + Parameters + ---------- + steps : int + Flag and number of time steps + doexit : int + Whether to exit from forecasts + py__next_observation_pdaf : Callable + Provide information on next forecast + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + outflag : int + Status flag + + Returns + ------- + steps : int + Flag and number of time steps + time : float + current model time + doexit : int + Whether to exit from forecasts + outflag : int + Status flag + """ diff --git a/pyPDAF/source/src/pyPDAF/PDAF/assim.pyx b/pyPDAF/source/src/pyPDAF/PDAF/assim.pyx new file mode 100644 index 0000000000000000000000000000000000000000..ba793117d6005152753a8073f1500e6a26ac50b2 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/assim.pyx @@ -0,0 +1,13512 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + + +def get_state(int steps, int doexit, py__next_observation_pdaf, + py__distribute_state_pdaf, py__prepoststep_pdaf, int outflag): + """get_state(steps:int, doexit:int, py__next_observation_pdaf:Callable, py__distribute_state_pdaf:Callable, py__prepoststep_pdaf:Callable, outflag:int) -> tuple[int, float, int, int] + + Distribute analysis state vector to an array. + + The primary purpose of this function is to distribute + the analysis state vector to the model. + This is attained by the user-supplied function + :func:`py__distribute_state_pdaf`. + One can also use this function to get the state vector + for other purposes, e.g. to write the state vector to a file. + + In this function, the user-supplied function + :func:`py__next_observation_pdaf` is executed + to specify the number of forecast time steps + until the next assimilation step. + One can also use the user-supplied function to + end the assimilation. + + In an online DA system, this function also execute + the user-supplied function :func:`py__prepoststep_state_pdaf`, + when this function is first called. The purpose of this design + is to call this function right after :func:`pyPDAF.PDAF.init` + to process the initial ensemble before using it to + initialse model forecast. This user-supplied function + will not be called afterwards. + + This function is also used in flexible parallel system + where the number of ensemble members are greater than + the parallel model tasks. In this case, this function + is called multiple times to distribute the analysis ensemble. + + User-supplied function are executed in the following sequence: + + 1. py__prepoststep_state_pdaf + (only in online system when first called) + 2. py__distribute_state_pdaf + 3. py__next_observation_pdaf + + Parameters + ---------- + steps : int + Flag and number of time steps + doexit : int + Whether to exit from forecasts + py__next_observation_pdaf : Callable + Provide information on next forecast + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + outflag : int + Status flag + + Returns + ------- + steps : int + Flag and number of time steps + time : double + current model time + doexit : int + Whether to exit from forecasts + outflag : int + Status flag + """ + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef double time + with nogil: + c__pdaf_get_state(&steps, &time, &doexit, + pdaf_cb.c__next_observation_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return steps, time, doexit, outflag + + +def assimilate_estkf(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__prepoststep_pdaf, py__prodrinva_pdaf, py__init_obsvar_pdaf, + py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_assimilate_global` + or :func:`pyPDAF.PDAF.omi_assimilate_global_nondiagR` + instead of this function. + + OMI functions need fewer user-supplied functions + and improve DA efficiency. + + This function calls ESTKF + (error space transform Kalman filter) [1]_. + The ESTKF is a more efficient equivalent to the ETKF. + + The function should be called at each model time step. + The function is a combination of + :func:`pyPDAF.PDAF.put_state_estkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for ensemble mean) + 5. py__init_obs_pdaf + 6. py__obs_op_pdaf (for each ensemble member) + 7. py__init_obsvar_pdaf (only relevant + for adaptive forgetting factor schemes) + 8. py__prodRinvA_pdaf + 9. core DA algorithm + 10. py__prepoststep_state_pdaf + 11. py__distribute_state_pdaf + 12. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_assimilate_global` + and :func:`pyPDAF.PDAF.omi_assimilate_global_nondiagR` + + References + ---------- + .. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf_assimilate_estkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assim_offline_estkf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__prepoststep_pdaf, py__prodrinva_pdaf, + py__init_obsvar_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + cdef int outflag + with nogil: + c__pdaf_assim_offline_estkf(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__init_obsvar_pdaf, &outflag) + + return outflag + + +def assimilate_3dvar(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__prodrinva_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_assimilate_3dvar` + or :func:`pyPDAF.PDAF.omi_assimilate_3dvar_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + 3DVar DA for a single step without OMI. + When 3DVar is used, the background error covariance matrix + has to be modelled for cotrol variable + transformation. This is a deterministic filtering + scheme so no ensemble and + parallelisation is needed. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_3dvar` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. Iterative optimisation: + 1. py__cvt_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_pdaf + 6. core DA algorithm + 7. py__cvt_pdaf + 8. py__prepoststep_state_pdaf + 9. py__distribute_state_pdaf + 10. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by :func:`pyPDAF.PDAF.omi_assimilate_3dvar` + and :func:`pyPDAF.PDAF.omi_assimilate_3dvar_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf_assimilate_3dvar(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assim_offline_3dvar(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__prodrinva_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf_assim_offline_3dvar(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def assimilate_en3dvar_lestkf(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__prodrinva_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, + py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, py__init_obs_f_pdaf, + py__init_obs_l_pdaf, py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, + py__l2g_state_pdaf, py__g2l_obs_pdaf, py__init_obsvar_pdaf, + py__init_obsvar_l_pdaf, py__prepoststep_pdaf, py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf` or + :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + 3DEnVar for a single DA step where the ensemble anomaly + is generated by LESTKF. + The background error covariance matrix is + estimated by ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An LESTKF is used to generate ensemble perturbations. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_en3dvar_lestkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. Starting the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core DA algorithm + 7. py__cvt_ens_pdaf + 8. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__init_obs_pdaf + (if global adaptive forgetting factor is used + `type_forget=1` in :func:`pyPDAF.PDAF.init`) + 5. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise mean ensemble in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local + adaptive forgetting factor + `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + 9. py__prepoststep_state_pdaf + 10. py__distribute_state_pdaf + 11. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf` + and + :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble var) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_f_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Size of the full observation vector + + Callback Returns + ---------------- + observation_f : ndarray[np.float64, ndim=1] + Full vector of observations + Array shape: (dim_obs_f) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.init_obs_f_pdaf = py__init_obs_f_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf_assimilate_en3dvar_lestkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__init_obs_f_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assim_offline_en3dvar_lestkf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__prodrinva_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, + py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, py__init_obs_f_pdaf, + py__init_obs_l_pdaf, py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, + py__l2g_state_pdaf, py__g2l_obs_pdaf, py__init_obsvar_pdaf, + py__init_obsvar_l_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble var) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_f_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Size of the full observation vector + + Callback Returns + ---------------- + observation_f : ndarray[np.float64, ndim=1] + Full vector of observations + Array shape: (dim_obs_f) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.init_obs_f_pdaf = py__init_obs_f_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf_assim_offline_en3dvar_lestkf(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__init_obs_f_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def assimilate_ensrf(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__init_obsvars_pdaf, py__localize_covar_serial_pdaf, + py__prepoststep_pdaf, py__next_observation_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obsvars_pdaf : Callable + Initialize vector of observation error variances + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Dimension of full observation vector + + Callback Returns + ---------------- + var_f : ndarray[np.float64, ndim=1] + vector of observation error variances + Array shape: (dim_obs_f) + + py__localize_covar_serial_pdaf : Callable + Apply localization for single-observation vectors + + Callback Parameters + ------------------- + iobs : int + Index of current observation + dim_p : int + Process-local state dimension + dim_obs : int + Number of observations + hp_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HP for observation iobs + Array shape: (dim_p) + hxy_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HX(HX_all) for full observations + Array shape: (dim_obs) + + Callback Returns + ---------------- + hp_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HP for observation iobs + Array shape: (dim_p) + hxy_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HX(HX_all) for full observations + Array shape: (dim_obs) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obsvars_pdaf = py__init_obsvars_pdaf + pdaf_cb.localize_covar_serial_pdaf = py__localize_covar_serial_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf_assimilate_ensrf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obsvars_pdaf, + pdaf_cb.c__localize_covar_serial_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assim_offline_ensrf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__init_obsvars_pdaf, + py__localize_covar_serial_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obsvars_pdaf : Callable + Initialize vector of observation error variances + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Dimension of full observation vector + + Callback Returns + ---------------- + var_f : ndarray[np.float64, ndim=1] + vector of observation error variances + Array shape: (dim_obs_f) + + py__localize_covar_serial_pdaf : Callable + Apply localization for single-observation vectors + + Callback Parameters + ------------------- + iobs : int + Index of current observation + dim_p : int + Process-local state dimension + dim_obs : int + Number of observations + hp_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HP for observation iobs + Array shape: (dim_p) + hxy_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HX(HX_all) for full observations + Array shape: (dim_obs) + + Callback Returns + ---------------- + hp_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HP for observation iobs + Array shape: (dim_p) + hxy_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HX(HX_all) for full observations + Array shape: (dim_obs) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obsvars_pdaf = py__init_obsvars_pdaf + pdaf_cb.localize_covar_serial_pdaf = py__localize_covar_serial_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf_assim_offline_ensrf(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obsvars_pdaf, + pdaf_cb.c__localize_covar_serial_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def assimilate_lknetf(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__init_obs_l_pdaf, py__prepoststep_pdaf, py__prodrinva_l_pdaf, + py__prodrinva_hyb_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, + py__l2g_state_pdaf, py__g2l_obs_pdaf, py__init_obsvar_pdaf, + py__init_obsvar_l_pdaf, py__likelihood_l_pdaf, + py__likelihood_hyb_l_pdaf, py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_assimilate` + or :func:`pyPDAF.PDAF.localomi_assimilate_lknetf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + A hybridised LETKF and LNETF [1]_ for a single DA step. + The LNETF computes the distribution up to + the second moment similar to Kalman filters but + using a nonlinear weighting similar to + particle filters. This leads to an equal weights + assumption for the prior ensemble. + The hybridisation with LETKF is expected to lead to + improved performance for quasi-Gaussian problems. + The function should be called at each model step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_lknetf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf + (for each ensemble member) + 6. py__init_obs_pdaf + (if global adaptive forgetting factor `type_forget=1` + is used in :func:`pyPDAF.PDAF.init`) + 7. py__init_obsvar_pdaf (if global adaptive + forgetting factor is used) + 8. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise each ensemble member + in observation space) + 5. py__init_obs_l_pdaf + 6. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting + factor `type_forget=2` is used) + 7. py__prodRinvA_pdaf + 8. py__likelihood_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + 9. py__obs_op_pdaf + (only called with `HKN` and `HNK` options + called for each ensemble member) + 10. py__likelihood_hyb_l_pda + 11. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting + factor `type_forget=2` is used) + 12. py__prodRinvA_hyb_l_pdaf + 13. py__prepoststep_state_pdaf + 14. py__distribute_state_pdaf + 15. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_assimilate` + and :func:`pyPDAF.PDAF.localomi_assimilate_lknetf_nondiagR` + + References + ---------- + .. [1] Nerger, L.. (2022) + Data assimilation for nonlinear systems with + a hybrid nonlinear Kalman ensemble transform filter. + Q J R Meteorol Soc, 620–640. doi:10.1002/qj.4221 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__prodrinva_hyb_l_pdaf : Callable + Provide product R^-1 A on local analysis domain with hybrid weight + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + dim_ens : int + Number of the columns in the matrix processes here. This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__likelihood_l_pdaf : Callable + Compute likelihood + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__likelihood_hyb_l_pdaf : Callable + Compute likelihood with hybrid weight + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.prodrinva_hyb_l_pdaf = py__prodrinva_hyb_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.likelihood_hyb_l_pdaf = py__likelihood_hyb_l_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf_assimilate_lknetf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__prodrinva_hyb_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__likelihood_hyb_l_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assim_offline_lknetf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__init_obs_l_pdaf, py__prepoststep_pdaf, + py__prodrinva_l_pdaf, py__prodrinva_hyb_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__g2l_obs_pdaf, py__init_obsvar_pdaf, py__init_obsvar_l_pdaf, + py__likelihood_l_pdaf, py__likelihood_hyb_l_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__prodrinva_hyb_l_pdaf : Callable + Provide product R^-1 A on local analysis domain with hybrid weight + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + dim_ens : int + Number of the columns in the matrix processes here. This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__likelihood_l_pdaf : Callable + Compute likelihood + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__likelihood_hyb_l_pdaf : Callable + Compute likelihood with hybrid weight + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.prodrinva_hyb_l_pdaf = py__prodrinva_hyb_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.likelihood_hyb_l_pdaf = py__likelihood_hyb_l_pdaf + cdef int outflag + with nogil: + c__pdaf_assim_offline_lknetf(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__prodrinva_hyb_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__likelihood_hyb_l_pdaf, &outflag) + + return outflag + + +def assimilate_hyb3dvar_estkf(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__prodrinva_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__init_obsvar_pdaf, + py__prepoststep_pdaf, py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_assimilate_hyb3dvar_estkf` + or :func:`pyPDAF.PDAF.omi_assimilate_hyb3dvar_estkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Hybrid 3DEnVar for a single DA step where + the background error covariance is hybridised by + a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + ESTKF in this implementation. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_hyb3dvar_estkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. the iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core 3DEnVar algorithm + 7. py__cvt_pdaf + 8. py__cvt_ens_pdaf + 9. Perform ESTKF: + 1. py__init_dim_obs_pdaf + 2. py__obs_op_pdaf + (for ensemble mean) + 3. py__init_obs_pdaf + 4. py__obs_op_pdaf + (for each ensemble member) + 5. py__init_obsvar_pdaf + (only relevant for adaptive + forgetting factor schemes) + 6. py__prodRinvA_pdaf + 7. core ESTKF algorithm + 10. py__prepoststep_state_pdaf + 11. py__distribute_state_pdaf + 12. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_assimilate_hyb3dvar_estkf` and + :func:`pyPDAF.PDAF.omi_assimilate_hyb3dvar_estkf_nondiagR`. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble var) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf_assimilate_hyb3dvar_estkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assim_offline_hyb3dvar_estkf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__prodrinva_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__init_obsvar_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble var) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf_assim_offline_hyb3dvar_estkf(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def assimilate_hyb3dvar_lestkf(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__prodrinva_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__init_dim_obs_f_pdaf, + py__obs_op_f_pdaf, py__init_obs_f_pdaf, py__init_obs_l_pdaf, + py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__g2l_obs_pdaf, py__init_obsvar_pdaf, py__init_obsvar_l_pdaf, + py__prepoststep_pdaf, py__next_observation_pdaf, int outflag): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf` or + :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Hybrid 3DEnVar for a single DA step where + the background error covariance is hybridised by + a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + LESTKF in this implementation. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_hyb3dvar_lestkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. The iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core DA algorithm + 7. py__cvt_pdaf + 8. py__cvt_ens_pdaf + 9. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__init_obs_pdaf + (if global adaptive forgetting factor + `type_forget=1` in :func:`pyPDAF.PDAF.init`) + 5. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise mean ensemble in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting + factor `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + 10. py__prepoststep_state_pdaf + 11. py__distribute_state_pdaf + 12. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf` + and + :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble var) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_f_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Size of the full observation vector + + Callback Returns + ---------------- + observation_f : ndarray[np.float64, ndim=1] + Full vector of observations + Array shape: (dim_obs_f) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.init_obs_f_pdaf = py__init_obs_f_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaf_assimilate_hyb3dvar_lestkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__init_obs_f_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assim_offline_hyb3dvar_lestkf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__prodrinva_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__init_dim_obs_f_pdaf, + py__obs_op_f_pdaf, py__init_obs_f_pdaf, py__init_obs_l_pdaf, + py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__g2l_obs_pdaf, py__init_obsvar_pdaf, py__init_obsvar_l_pdaf, + py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble var) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_f_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Size of the full observation vector + + Callback Returns + ---------------- + observation_f : ndarray[np.float64, ndim=1] + Full vector of observations + Array shape: (dim_obs_f) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.init_obs_f_pdaf = py__init_obs_f_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf_assim_offline_hyb3dvar_lestkf(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__init_obs_f_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def assimilate_lestkf(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__init_obs_l_pdaf, py__prepoststep_pdaf, py__prodrinva_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__g2l_obs_pdaf, py__init_obsvar_pdaf, py__init_obsvar_l_pdaf, + py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_assimilate` + or :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`. + + PDAFlocal-OMI modules require fewer user-supplied + functions and improved efficiency. + + Local ESTKF (error space transform Kalman filter) [1]_ for a single DA step without OMI. + The LESTKF is a more efficient equivalent to the LETKF. + + This function should be called at each model time step. + The function is a combination of + :func:`pyPDAF.PDAF.put_state_lestkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. py__init_obs_pdaf + (if global adaptive forgetting factor + `type_forget=1` is used + in :func:`pyPDAF.PDAF.init`) + 7. py__init_obsvar_pdaf (if global adaptive + forgetting factor is used) + 8. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf (localise mean ensemble + in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive + forgetting factor `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + 9. py__prepoststep_state_pdaf + 10. py__distribute_state_pdaf + 11. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_assimilate` + and :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR` + + References + ---------- + .. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf_assimilate_lestkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assim_offline_lestkf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__init_obs_l_pdaf, py__prepoststep_pdaf, + py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__g2l_obs_pdaf, py__init_obsvar_pdaf, py__init_obsvar_l_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + cdef int outflag + with nogil: + c__pdaf_assim_offline_lestkf(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, &outflag) + + return outflag + + +def assimilate_enkf(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__prepoststep_pdaf, py__add_obs_err_pdaf, py__init_obs_covar_pdaf, + py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_assimilate_global` + or :func:`pyPDAF.PDAF.omi_assimilate_enkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Stochastic EnKF (ensemble Kalman filter) [1]_ for a single DA step without OMI. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_enkf` and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for ensemble mean) + 5. py__add_obs_err_pdaf + 6. py__init_obs_pdaf + 7. py__init_obscovar_pdaf + 8. py__obs_op_pdaf (for each ensemble member) + 9. core DA algorithm + 10. py__prepoststep_state_pdaf + 11. py__distribute_state_pdaf + 12. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_assimilate_global` + and :func:`pyPDAF.PDAF.omi_assimilate_enkf_nondiagR` + + References + ---------- + .. [1] Evensen, G. (1994), + Sequential data assimilation with a nonlinear + quasi-geostrophic model + using Monte Carlo methods to forecast error statistics, + J. Geophys. Res., 99(C5), 10143–10162, + doi:10.1029/94JC00572. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__add_obs_err_pdaf : Callable + Add obs error covariance R to HPH in EnKF + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Dimension of observation vector + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + py__init_obs_covar_pdaf : Callable + Initialize obs. error cov. matrix R in EnKF + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs : int + Global size of observation vector + dim_obs_p : int + Size of process-local observation vector + obs_p : ndarray[np.float64, ndim=1] + Process-local vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + covar : ndarray[np.float64, ndim=2] + Observation error covariance matrix + Array shape: (dim_obs_p,dim_obs_p) + isdiag : bint + + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf_assimilate_enkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assim_offline_enkf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__prepoststep_pdaf, py__add_obs_err_pdaf, + py__init_obs_covar_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__add_obs_err_pdaf : Callable + Add obs error covariance R to HPH in EnKF + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Dimension of observation vector + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + py__init_obs_covar_pdaf : Callable + Initialize obs. error cov. matrix R in EnKF + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs : int + Global size of observation vector + dim_obs_p : int + Size of process-local observation vector + obs_p : ndarray[np.float64, ndim=1] + Process-local vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + covar : ndarray[np.float64, ndim=2] + Observation error covariance matrix + Array shape: (dim_obs_p,dim_obs_p) + isdiag : bint + + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + cdef int outflag + with nogil: + c__pdaf_assim_offline_enkf(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, &outflag) + + return outflag + + +def assimilate_letkf(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__init_obs_l_pdaf, py__prepoststep_pdaf, py__prodrinva_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__g2l_obs_pdaf, py__init_obsvar_pdaf, py__init_obsvar_l_pdaf, + py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_assimilate` + or :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`. + + PDAFlocal-OMI modules require fewer user-supplied + functions and improved efficiency. + + Local ensemble transform Kalman filter (LETKF) [1]_ for a single DA step without OMI. + Implementation is based on [2]_. + Note that the LESTKF is a more efficient equivalent + to the LETKF. + + This function should be called at each model time step. + The function is a combination of + :func:`pyPDAF.PDAF.put_state_letkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. py__init_obs_pdaf + (if global adaptive forgetting factor + `type_forget=1` is used + in :func:`pyPDAF.PDAF.init`) + 7. py__init_obsvar_pdaf (if global adaptive + forgetting factor is used) + 8. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf (localise mean ensemble + in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting factor + `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + 9. py__prepoststep_state_pdaf + 10. py__distribute_state_pdaf + 11. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_assimilate` + and :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR` + + References + ---------- + .. [1] Hunt, B. R., Kostelich, E. J., & Szunyogh, I. (2007). + Efficient data assimilation for spatiotemporal chaos: + A local ensemble transform Kalman filter. + Physica D: Nonlinear Phenomena, 230(1-2), 112-126. + .. [2] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf_assimilate_letkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assim_offline_letkf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__init_obs_l_pdaf, py__prepoststep_pdaf, + py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__g2l_obs_pdaf, py__init_obsvar_pdaf, py__init_obsvar_l_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + cdef int outflag + with nogil: + c__pdaf_assim_offline_letkf(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, &outflag) + + return outflag + + +def assimilate_seik(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__prepoststep_pdaf, py__prodrinva_pdaf, py__init_obsvar_pdaf, + py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_assimilate_global` + or :func:`pyPDAF.PDAF.omi_assimilate_global_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + This function will use singular evolutive + interpolated Kalman filter [1]_ for a single DA step. + The function should be called at each model step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_seik` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for ensemble mean) + 5. py__init_obs_pdaf + 6. py__obs_op_pdaf (for each ensemble member) + 7. py__init_obsvar_pdaf (only relevant for + adaptive forgetting factor schemes) + 8. py__prodRinvA_pdaf + 9. core DA algorithm + 10. py__prepoststep_state_pdaf + 11. py__distribute_state_pdaf + 12. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_assimilate_global` + and :func:`pyPDAF.PDAF.omi_assimilate_global_nondiagR` + + References + ---------- + .. [1] Pham, D. T., Verron, J., & Roubaud, M. C. (1998). + A singular evolutive extended Kalman + filter for data assimilation + in oceanography. Journal of Marine systems, + 16(3-4), 323-340. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf_assimilate_seik(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assim_offline_seik(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__prepoststep_pdaf, py__prodrinva_pdaf, + py__init_obsvar_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + cdef int outflag + with nogil: + c__pdaf_assim_offline_seik(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__init_obsvar_pdaf, &outflag) + + return outflag + + +def assimilate_lnetf(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__init_obs_l_pdaf, py__prepoststep_pdaf, py__likelihood_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__g2l_obs_pdaf, py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_assimilate` + or :func:`pyPDAF.PDAF.localomi_assimilate_lnetf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Local Nonlinear Ensemble Transform Filter (LNETF) [1]_ + for a single DA step. + The nonlinear filter computes the distribution up to + the second moment similar to Kalman filters but + it uses a nonlinear weighting similar to + particle filters. This leads to an equal weights assumption + for the prior ensemble at each step. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_lnetf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__init_obs_l_pdaf + 5. py__g2l_obs_pdaf (localise each ensemble + member in observation space) + 6. py__likelihood_l_pdaf + 7. core DA algorithm + 8. py__l2g_state_pdaf + 7. py__prepoststep_state_pdaf + 8. py__distribute_state_pdaf + 9. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_assimilate` + and :func:`pyPDAF.PDAF.localomi_assimilate_lnetf_nondiagR` + + References + ---------- + .. [1] Tödter, J., and B. Ahrens, 2015: + A second-order exact ensemble square root filter + for nonlinear data assimilation. Mon. Wea. Rev., + 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__likelihood_l_pdaf : Callable + Compute observation likelihood for an ensemble member + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf_assimilate_lnetf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assim_offline_lnetf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__init_obs_l_pdaf, py__prepoststep_pdaf, + py__likelihood_l_pdaf, py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__g2l_obs_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__likelihood_l_pdaf : Callable + Compute observation likelihood for an ensemble member + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + cdef int outflag + with nogil: + c__pdaf_assim_offline_lnetf(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, &outflag) + + return outflag + + +def assimilate_prepost(py__collect_state_pdaf, py__distribute_state_pdaf, + py__prepoststep_pdaf, py__next_observation_pdaf): + """It is used to preprocess and postprocess of the ensemble. + + No DA is performed in this function. + Compared to :func:`pyPDAF.PDAF.prepost`, + this function sets assimilation flag, + which means that it is acted as an assimilation in PDAF. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_prepost` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf (preprocess, step < 0) + 3. py__prepoststep_state_pdaf (postprocess, step > 0) + 4. py__distribute_state_pdaf + 5. py__next_observation_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf_assimilate_prepost(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assimilate_en3dvar_estkf(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__prodrinva_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, + py__init_obsvar_pdaf, py__prepoststep_pdaf, py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_assimilate_en3dvar_estkf` + or :func:`pyPDAF.PDAF.omi_assimilate_en3dvar_estkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + 3DEnVar for a single DA step. + The background error covariance matrix is estimated + by an ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An ESTKF is used along with 3DEnVar + to generate ensemble perturbations. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_en3dvar_estkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core 3DEnVar algorithm + 7. py__cvt_ens_pdaf + 8. ESTKF: + 1. py__init_dim_obs_pdaf + 2. py__obs_op_pdaf (for ensemble mean) + 3. py__init_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. py__init_obsvar_pdaf + (only relevant for adaptive + forgetting factor schemes) + 6. py__prodRinvA_pdaf + 7. core ESTKF algorithm + 9. py__prepoststep_state_pdaf + 10. py__distribute_state_pdaf + 11. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_assimilate_en3dvar_estkf` + and :func:`pyPDAF.PDAF.omi_assimilate_en3dvar_estkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble var) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf_assimilate_en3dvar_estkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assim_offline_en3dvar_estkf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__prodrinva_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, + py__init_obsvar_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble var) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf_assim_offline_en3dvar_estkf(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def assimilate_netf(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__prepoststep_pdaf, py__likelihood_pdaf, py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_assimilate_global` + or :func:`pyPDAF.PDAF.omi_assimilate_nonlin_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + This function will use Nonlinear Ensemble + Transform Filter (NETF) [1]_ + for a single DA step. The nonlinear filter + computes the distribution up to + the second moment similar to KF but using + a nonlinear weighting similar to + particle filter. This leads to an equal + weights assumption for prior ensemble. + The function should be called at each model step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_netf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__init_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. py__likelihood_pdaf + 7. core DA algorithm + 8. py__prepoststep_state_pdaf + 9. py__distribute_state_pdaf + 10. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_assimilate_global` + and :func:`pyPDAF.PDAF.omi_assimilate_nonlin_nondiagR` + + References + ---------- + .. [1] Tödter, J., and B. Ahrens, 2015: + A second-order exact ensemble square root filter + for nonlinear data assimilation. Mon. Wea. Rev., + 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__likelihood_pdaf : Callable + Compute observation likelihood for an ensemble member + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + resid : ndarray[np.float64, ndim=1] + Input vector holding the residual + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + likely : double + Output value of the likelihood + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.likelihood_pdaf = py__likelihood_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf_assimilate_netf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__likelihood_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assim_offline_netf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__prepoststep_pdaf, py__likelihood_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__likelihood_pdaf : Callable + Compute observation likelihood for an ensemble member + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + resid : ndarray[np.float64, ndim=1] + Input vector holding the residual + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + likely : double + Output value of the likelihood + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.likelihood_pdaf = py__likelihood_pdaf + cdef int outflag + with nogil: + c__pdaf_assim_offline_netf(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__likelihood_pdaf, &outflag) + + return outflag + + +def assimilate_pf(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__prepoststep_pdaf, py__likelihood_pdaf, py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_assimilate_global` + or :func:`pyPDAF.PDAF.omi_assimilate_nonlin_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + This function will use particle filter for a single DA step. + This is a fully nonlinear filter, and may require + a high number of ensemble members. + A review of particle filter can be found at [1]_. + The function should be called at each model step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_pf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__init_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. py__likelihood_pdaf + 7. core DA algorithm + 8. py__prepoststep_state_pdaf + 9. py__distribute_state_pdaf + 10. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_assimilate_global` + and :func:`pyPDAF.PDAF.omi_assimilate_nonlin_nondiagR` + + References + ---------- + .. [1] Van Leeuwen, P. J., Künsch, H. R., + Nerger, L., Potthast, R., & Reich, S. (2019). + Particle filters for high‐dimensional geoscience + applications: + A review. Quarterly Journal of the Royal + Meteorological Society, 145(723), 2335-2365. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__likelihood_pdaf : Callable + Compute observation likelihood for an ensemble member + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + resid : ndarray[np.float64, ndim=1] + Input vector holding the residual + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + likely : double + Output value of the likelihood + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.likelihood_pdaf = py__likelihood_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf_assimilate_pf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__likelihood_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assim_offline_pf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__prepoststep_pdaf, py__likelihood_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__likelihood_pdaf : Callable + Compute observation likelihood for an ensemble member + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + resid : ndarray[np.float64, ndim=1] + Input vector holding the residual + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + likely : double + Output value of the likelihood + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.likelihood_pdaf = py__likelihood_pdaf + cdef int outflag + with nogil: + c__pdaf_assim_offline_pf(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__likelihood_pdaf, &outflag) + + return outflag + + +def assimilate_lenkf(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__prepoststep_pdaf, py__localize_covar_pdaf, py__add_obs_err_pdaf, + py__init_obs_covar_pdaf, py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_assimilate_lenkf` + or :func:`pyPDAF.PDAF.omi_assimilate_lenkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Stochastic EnKF (ensemble Kalman filter) + with covariance localisation [1]_ + for a single DA step without OMI. + + This is the only scheme for covariance localisation in PDAF. + + This function should be called at each model time step. + The function is a combination of + :func:`pyPDAF.PDAF.put_state_lenkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. py__localize_pdaf + 6. py__add_obs_err_pdaf + 7. py__init_obs_pdaf + 8. py__init_obscovar_pdaf + 9. py__obs_op_pdaf (repeated to reduce storage) + 10. core DA algorith + 11. py__prepoststep_state_pdaf + 12. py__distribute_state_pdaf + 13. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_assimilate_lenkf` + and :func:`pyPDAF.PDAF.omi_assimilate_lenkf_nondiagR` + + References + ---------- + .. [1] Houtekamer, P. L., and H. L. Mitchell (1998): + Data Assimilation Using an Ensemble Kalman Filter + Technique. + Mon. Wea. Rev., 126, 796–811, + doi: 10.1175/1520-0493(1998)126<0796:DAUAEK>2.0.CO;2. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__localize_covar_pdaf : Callable + Apply localization to HP and HPH^T + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + dim_obs : int + number of observations + hp_p : ndarray[np.float64, ndim=2] + pe local part of matrix hp + Array shape: (dim_obs, dim_p) + hph : ndarray[np.float64, ndim=2] + matrix hph + Array shape: (dim_obs, dim_obs) + + Callback Returns + ---------------- + hp_p : ndarray[np.float64, ndim=2] + pe local part of matrix hp + Array shape: (dim_obs, dim_p) + hph : ndarray[np.float64, ndim=2] + matrix hph + Array shape: (dim_obs, dim_obs) + + py__add_obs_err_pdaf : Callable + Add obs error covariance R to HPH in EnKF + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Dimension of observation vector + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + py__init_obs_covar_pdaf : Callable + Initialize obs. error cov. matrix R in EnKF + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs : int + Global size of observation vector + dim_obs_p : int + Size of process-local observation vector + obs_p : ndarray[np.float64, ndim=1] + Process-local vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + covar : ndarray[np.float64, ndim=2] + Observation error covariance matrix + Array shape: (dim_obs_p,dim_obs_p) + isdiag : bint + + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.localize_covar_pdaf = py__localize_covar_pdaf + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf_assimilate_lenkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__localize_covar_pdaf, + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assim_offline_lenkf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__prepoststep_pdaf, py__localize_covar_pdaf, + py__add_obs_err_pdaf, py__init_obs_covar_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__localize_covar_pdaf : Callable + Apply localization to HP and HPH^T + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + dim_obs : int + number of observations + hp_p : ndarray[np.float64, ndim=2] + pe local part of matrix hp + Array shape: (dim_obs, dim_p) + hph : ndarray[np.float64, ndim=2] + matrix hph + Array shape: (dim_obs, dim_obs) + + Callback Returns + ---------------- + hp_p : ndarray[np.float64, ndim=2] + pe local part of matrix hp + Array shape: (dim_obs, dim_p) + hph : ndarray[np.float64, ndim=2] + matrix hph + Array shape: (dim_obs, dim_obs) + + py__add_obs_err_pdaf : Callable + Add obs error covariance R to HPH in EnKF + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Dimension of observation vector + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + py__init_obs_covar_pdaf : Callable + Initialize obs. error cov. matrix R in EnKF + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs : int + Global size of observation vector + dim_obs_p : int + Size of process-local observation vector + obs_p : ndarray[np.float64, ndim=1] + Process-local vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + covar : ndarray[np.float64, ndim=2] + Observation error covariance matrix + Array shape: (dim_obs_p,dim_obs_p) + isdiag : bint + + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.localize_covar_pdaf = py__localize_covar_pdaf + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + cdef int outflag + with nogil: + c__pdaf_assim_offline_lenkf(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__localize_covar_pdaf, + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, &outflag) + + return outflag + + +def assimilate_etkf(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__prepoststep_pdaf, py__prodrinva_pdaf, py__init_obsvar_pdaf, + py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_assimilate_global` + or :func:`pyPDAF.PDAF.omi_assimilate_global_nondiagR`. + + PDAFlocal-OMI modules require fewer + user-supplied functions and improved efficiency. + + Using ETKF (ensemble transform + Kalman filter) [1]_ for a single DA step without OMI. + The implementation is baed on [2]_. + + This function should be called at each model time step. + The function is a combination of + :func:`pyPDAF.PDAF.put_state_etkf` and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for ensemble mean) + 5. py__init_obs_pdaf + 6. py__obs_op_pdaf (for each ensemble member) + 7. py__init_obsvar_pdaf (only relevant for + adaptive forgetting factor schemes) + 8. py__prodRinvA_pdaf + 9. core DA algorithm + 10. py__prepoststep_state_pdaf + 11. py__distribute_state_pdaf + 12. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_assimilate_global` + and :func:`pyPDAF.PDAF.omi_assimilate_global_nondiagR` + + References + ---------- + .. [1] Bishop, C. H., B. J. Etherton, and S. J. Majumdar (2001) + Adaptive Sampling with the Ensemble + Transform Kalman Filter. + Part I: Theoretical Aspects. Mon. Wea. Rev., + 129, 420–436, + doi: 10.1175/1520-0493(2001)129<0420:ASWTET>2.0.CO;2. + .. [2] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf_assimilate_etkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assim_offline_etkf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__prepoststep_pdaf, py__prodrinva_pdaf, + py__init_obsvar_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + cdef int outflag + with nogil: + c__pdaf_assim_offline_etkf(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__init_obsvar_pdaf, &outflag) + + return outflag + + +def assimilate_lseik(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__init_obs_l_pdaf, py__prepoststep_pdaf, py__prodrinva_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__g2l_obs_pdaf, py__init_obsvar_pdaf, py__init_obsvar_l_pdaf, + py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_assimilate` + or :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`. + + PDAF-OMI modules require fewer user-supplied + functions and improved efficiency. + + Local singular evolutive interpolated Kalman filter [1]_ + for a single DA step. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_lseik` and :func:`pyPDAF.PDAF.get_state` + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. py__init_obs_pdaf + (if global adaptive forgetting factor `type_forget=1` + is used in :func:`pyPDAF.PDAF.init`) + 7. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 8. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf (localise mean ensemble + in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting + factor `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + 9. py__prepoststep_state_pdaf + 10. py__distribute_state_pdaf + 11. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_assimilate` + and :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR` + + References + ---------- + .. [1] Pham, D. T., Verron, J., & Roubaud, M. C. (1998). + A singular evolutive extended Kalman filter + for data assimilation + in oceanography. Journal of Marine systems, + 16(3-4), 323-340. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf_assimilate_lseik(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assim_offline_lseik(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__init_obs_l_pdaf, py__prepoststep_pdaf, + py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__g2l_obs_pdaf, py__init_obsvar_pdaf, py__init_obsvar_l_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + cdef int outflag + with nogil: + c__pdaf_assim_offline_lseik(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, &outflag) + + return outflag + + +def generate_obs(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, py__init_obserr_f_pdaf, + py__get_obs_f_pdaf, py__prepoststep_pdaf, py__next_observation_pdaf): + """Generation of synthetic observations based on + given error statistics and observation operator. + + When diagonal observation error covariance matrix is used, + it is recommended to use + :func:`pyPDAF.PDAF.omi_generate_obs` functionalities + for fewer user-supplied functions and improved efficiency. + + The generated synthetic observations are based on + each member of model forecast. + Therefore, an ensemble of observations can be obtained. + In a typical experiment, + one may only need one ensemble member. + The implementation strategy is similar to + an assimilation step. This means that, + one can reuse many user-supplied functions for + assimilation and observation generation. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_generate_obs` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pda + 5. py__init_obserr_f_pdaf + 6. py__get_obs_f_pdaf + 7. py__prepoststep_state_pdaf + 8. py__distribute_state_pdaf + 9. py__next_observation_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obserr_f_pdaf : Callable + Initialize vector of observation error standard deviations + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Full dimension of observation vector + obs_f : ndarray[np.float64, ndim=1] + Full observation vector + Array shape: (dim_obs_f) + + Callback Returns + ---------------- + obserr_f : ndarray[np.float64, ndim=1] + Full observation error stddev + Array shape: (dim_obs_f) + + py__get_obs_f_pdaf : Callable + Provide observation vector to user + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Size of the full observation vector + + Callback Returns + ---------------- + observation_f : ndarray[np.float64, ndim=1] + Full vector of synthetic observations (process-local) + Array shape: (dim_obs_f) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.init_obserr_f_pdaf = py__init_obserr_f_pdaf + pdaf_cb.get_obs_f_pdaf = py__get_obs_f_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf_generate_obs(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__init_obserr_f_pdaf, + pdaf_cb.c__get_obs_f_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def generate_obs_offline(py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, + py__init_obserr_f_pdaf, py__get_obs_f_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obserr_f_pdaf : Callable + Initialize vector of observation error standard deviations + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Full dimension of observation vector + obs_f : ndarray[np.float64, ndim=1] + Full observation vector + Array shape: (dim_obs_f) + + Callback Returns + ---------------- + obserr_f : ndarray[np.float64, ndim=1] + Full observation error stddev + Array shape: (dim_obs_f) + + py__get_obs_f_pdaf : Callable + Provide observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Size of the full observation vector + + Callback Returns + ---------------- + observation_f : ndarray[np.float64, ndim=1] + Full vector of synthetic observations (process-local) + Array shape: (dim_obs_f) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.init_obserr_f_pdaf = py__init_obserr_f_pdaf + pdaf_cb.get_obs_f_pdaf = py__get_obs_f_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf_generate_obs_offline(pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__init_obserr_f_pdaf, + pdaf_cb.c__get_obs_f_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + diff --git a/pyPDAF/source/src/pyPDAF/PDAF/callback.pxd b/pyPDAF/source/src/pyPDAF/PDAF/callback.pxd new file mode 100644 index 0000000000000000000000000000000000000000..ab1a54b8d73ef62c696d12bf894304109a1a19ac --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/callback.pxd @@ -0,0 +1,66 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t +cdef extern void c__pdafomi_init_obs_f_cb(int* step, int* dim_obs_f, + double* observation_f) noexcept nogil; + +cdef extern void c__pdafomi_init_obsvar_cb(int* step, int* dim_obs_p, + double* obs_p, double* meanvar) noexcept nogil; + +cdef extern void c__pdafomi_init_obsvars_f_cb(int* step, int* dim_obs_f, + double* var_f) noexcept nogil; + +cdef extern void c__pdafomi_g2l_obs_cb(int* domain_p, int* step, + int* dim_obs_f, int* dim_obs_l, double* ostate_f, + double* ostate_l) noexcept nogil; + +cdef extern void c__pdafomi_init_obs_l_cb(int* domain_p, int* step, + int* dim_obs_l, double* observation_l) noexcept nogil; + +cdef extern void c__pdafomi_init_obsvar_l_cb(int* domain_p, int* step, + int* dim_obs_l, double* obs_l, + double* meanvar_l) noexcept nogil; + +cdef extern void c__pdafomi_prodrinva_l_cb(int* domain_p, int* step, + int* dim_obs_l, int* rank, double* obs_l, double* a_l, + double* c_l) noexcept nogil; + +cdef extern void c__pdafomi_likelihood_l_cb(int* domain_p, int* step, + int* dim_obs_l, double* obs_l, double* resid_l, + double* lhood_l) noexcept nogil; + +cdef extern void c__pdafomi_prodrinva_hyb_l_cb(int* domain_p, int* step, + int* dim_obs_l, int* rank, double* obs_l, double* alpha, double* a_l, + double* c_l) noexcept nogil; + +cdef extern void c__pdafomi_likelihood_hyb_l_cb(int* domain_p, int* step, + int* dim_obs_l, double* obs_l, double* resid_l, double* alpha, + double* lhood_l) noexcept nogil; + +cdef extern void c__pdafomi_prodrinva_cb(int* step, int* dim_obs_p, + int* ncol, double* obs_p, double* a_p, + double* c_p) noexcept nogil; + +cdef extern void c__pdafomi_likelihood_cb(int* step, int* dim_obs, + double* obs, double* resid, double* lhood) noexcept nogil; + +cdef extern void c__pdafomi_add_obs_error_cb(int* step, int* dim_obs_p, + double* c_p) noexcept nogil; + +cdef extern void c__pdafomi_init_obscovar_cb(int* step, int* dim_obs, + int* dim_obs_p, double* covar, double* m_state_p, + bint* isdiag) noexcept nogil; + +cdef extern void c__pdafomi_init_obserr_f_cb(int* step, int* dim_obs_f, + double* obs_f, double* obserr_f) noexcept nogil; + +cdef extern void c__pdafomi_localize_covar_cb(int* dim_p, int* dim_obs, + double* hp_p, double* hph) noexcept nogil; + +cdef extern void c__pdafomi_localize_covar_serial_cb(int* iobs, int* dim_p, + int* dim_obs, double* hp_p, double* hxy_p) noexcept nogil; + +cdef extern void c__pdafomi_omit_by_inno_l_cb(int* domain_p, + int* dim_obs_l, double* resid_l, + double* obs_l) noexcept nogil; + +cdef extern void c__pdafomi_omit_by_inno_cb(int* dim_obs_f, + double* resid_f, double* obs_f) noexcept nogil; diff --git a/pyPDAF/source/src/pyPDAF/PDAF/callback.pyx b/pyPDAF/source/src/pyPDAF/PDAF/callback.pyx new file mode 100644 index 0000000000000000000000000000000000000000..636af8928b0bbc688f5b767b4649ea1514671971 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/callback.pyx @@ -0,0 +1,663 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + +try: + import mpi4py + mpi4py.rc.initialize = False +except ImportError: + pass + +# Global error handler +def global_except_hook(exctype, value, traceback): + from traceback import print_exception + try: + import mpi4py.MPI + + if mpi4py.MPI.Is_initialized(): + try: + sys.stderr.write('Uncaught exception was ''detected on rank {}.\n'.format( + mpi4py.MPI.COMM_WORLD.Get_rank())) + print_exception(exctype, value, traceback) + sys.stderr.write("\n") + sys.stderr.flush() + finally: + try: + mpi4py.MPI.COMM_WORLD.Abort(1) + except Exception as e: + sys.stderr.write('MPI Abort failed, this process will hang.\n') + sys.stderr.flush() + raise e + else: + sys.__excepthook__(exctype, value, traceback) + except ImportError: + sys.__excepthook__(exctype, value, traceback) + +sys.excepthook = global_except_hook + +def init_obs_f_cb(int step, int dim_obs_f): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_obs_f : int + Dimension of full observation vector + + Returns + ------- + observation_f : ndarray[np.float64, ndim=1] + Full observation vector + Array shape: (dim_obs_f) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] observation_f_np = np.zeros((dim_obs_f), dtype=np.float64, order="F") + cdef double [::1] observation_f = observation_f_np + with nogil: + c__pdafomi_init_obs_f_cb(&step, &dim_obs_f, &observation_f[0]) + + return observation_f_np + + +def init_obsvar_cb(int step, int dim_obs_p, double [::1] obs_p): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_obs_p : int + PE-local dimension of observation vector + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + + Returns + ------- + meanvar : double + Mean observation error variance + """ + cdef double meanvar + with nogil: + c__pdafomi_init_obsvar_cb(&step, &dim_obs_p, &obs_p[0], &meanvar) + + return meanvar + + +def init_obsvars_f_cb(int step, int dim_obs_f): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_obs_f : int + Dimension of full observation vector + + Returns + ------- + var_f : ndarray[np.float64, ndim=1] + vector of observation error variances + Array shape: (dim_obs_f) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] var_f_np = np.zeros((dim_obs_f), dtype=np.float64, order="F") + cdef double [::1] var_f = var_f_np + with nogil: + c__pdafomi_init_obsvars_f_cb(&step, &dim_obs_f, &var_f[0]) + + return var_f_np + + +def g2l_obs_cb(int domain_p, int step, int dim_obs_f, int dim_obs_l, + double [::1] ostate_f): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Dimension of full PE-local observation vector + dim_obs_l : int + Dimension of local observation vector + ostate_f : ndarray[np.float64, ndim=1] + Full PE-local obs.ervation vector + Array shape: (dim_obs_f) + + Returns + ------- + ostate_l : ndarray[np.float64, ndim=1] + Observation vector on local domain + Array shape: (dim_obs_l) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] ostate_l_np = np.zeros((dim_obs_l), dtype=np.float64, order="F") + cdef double [::1] ostate_l = ostate_l_np + with nogil: + c__pdafomi_g2l_obs_cb(&domain_p, &step, &dim_obs_f, &dim_obs_l, + &ostate_f[0], &ostate_l[0]) + + return ostate_l_np + + +def init_obs_l_cb(int domain_p, int step, int dim_obs_l): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Index of current local analysis domain index + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + + Returns + ------- + observation_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_l) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] observation_l_np = np.zeros((dim_obs_l), dtype=np.float64, order="F") + cdef double [::1] observation_l = observation_l_np + with nogil: + c__pdafomi_init_obs_l_cb(&domain_p, &step, &dim_obs_l, + &observation_l[0]) + + return observation_l_np + + +def init_obsvar_l_cb(int domain_p, int step, int dim_obs_l, + double [::1] obs_l): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_l) + + Returns + ------- + meanvar_l : double + Mean local observation error variance + """ + cdef double meanvar_l + with nogil: + c__pdafomi_init_obsvar_l_cb(&domain_p, &step, &dim_obs_l, + &obs_l[0], &meanvar_l) + + return meanvar_l + + +def prodrinva_l_cb(int domain_p, int step, int dim_obs_l, int rank, + double [::1] obs_l, double [::1,:] a_l): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Dimension of local observation vector + rank : int + Rank of initial covariance matrix + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix + Array shape: (dim_obs_l, rank) + + Returns + ------- + a_l : ndarray[np.float64, ndim=2] + Input matrix + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] a_l_np = np.asarray(a_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] c_l_np = np.zeros((dim_obs_l, rank), dtype=np.float64, order="F") + cdef double [::1,:] c_l = c_l_np + with nogil: + c__pdafomi_prodrinva_l_cb(&domain_p, &step, &dim_obs_l, &rank, + &obs_l[0], &a_l[0,0], &c_l[0,0]) + + return a_l_np, c_l_np + + +def likelihood_l_cb(int domain_p, int step, int dim_obs_l, + double [::1] obs_l, double [::1] resid_l): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + step : int + Current time step + dim_obs_l : int + PE-local dimension of obs. vector + obs_l : ndarray[np.float64, ndim=1] + PE-local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + Input vector of residuum + Array shape: (dim_obs_l) + + Returns + ------- + resid_l : ndarray[np.float64, ndim=1] + Input vector of residuum + Array shape: (dim_obs_l) + lhood_l : double + Output vector - log likelihood + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] resid_l_np = np.asarray(resid_l, dtype=np.float64, order="F") + cdef double lhood_l + with nogil: + c__pdafomi_likelihood_l_cb(&domain_p, &step, &dim_obs_l, &obs_l[0], + &resid_l[0], &lhood_l) + + return resid_l_np, lhood_l + + +def prodrinva_hyb_l_cb(int domain_p, int step, int dim_obs_l, int rank, + double [::1] obs_l, double alpha, double [::1,:] a_l): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Dimension of local observation vector + rank : int + Rank of initial covariance matrix + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + alpha : double + Hybrid weight + a_l : ndarray[np.float64, ndim=2] + Input matrix + Array shape: (dim_obs_l, rank) + + Returns + ------- + a_l : ndarray[np.float64, ndim=2] + Input matrix + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] a_l_np = np.asarray(a_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] c_l_np = np.zeros((dim_obs_l, rank), dtype=np.float64, order="F") + cdef double [::1,:] c_l = c_l_np + with nogil: + c__pdafomi_prodrinva_hyb_l_cb(&domain_p, &step, &dim_obs_l, &rank, + &obs_l[0], &alpha, &a_l[0,0], &c_l[0,0]) + + return a_l_np, c_l_np + + +def likelihood_hyb_l_cb(int domain_p, int step, int dim_obs_l, + double [::1] obs_l, double [::1] resid_l, double alpha): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + step : int + Current time step + dim_obs_l : int + PE-local dimension of obs. vector + obs_l : ndarray[np.float64, ndim=1] + PE-local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + Input vector of residuum + Array shape: (dim_obs_l) + alpha : double + Hybrid weight + + Returns + ------- + resid_l : ndarray[np.float64, ndim=1] + Input vector of residuum + Array shape: (dim_obs_l) + lhood_l : double + Output vector - log likelihood + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] resid_l_np = np.asarray(resid_l, dtype=np.float64, order="F") + cdef double lhood_l + with nogil: + c__pdafomi_likelihood_hyb_l_cb(&domain_p, &step, &dim_obs_l, + &obs_l[0], &resid_l[0], &alpha, &lhood_l) + + return resid_l_np, lhood_l + + +def prodrinva_cb(int step, int dim_obs_p, int ncol, double [::1] obs_p, + double [::1,:] a_p): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_obs_p : int + Dimension of PE-local observation vector + ncol : int + Number of columns in A_p and C_p + obs_p : ndarray[np.float64, ndim=1] + PE-local vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix + Array shape: (dim_obs_p, ncol) + + Returns + ------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, ncol) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] c_p_np = np.zeros((dim_obs_p, ncol), dtype=np.float64, order="F") + cdef double [::1,:] c_p = c_p_np + with nogil: + c__pdafomi_prodrinva_cb(&step, &dim_obs_p, &ncol, &obs_p[0], + &a_p[0,0], &c_p[0,0]) + + return c_p_np + + +def likelihood_cb(int step, int dim_obs, double [::1] obs, + double [::1] resid): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_obs : int + PE-local dimension of obs. vector + obs : ndarray[np.float64, ndim=1] + PE-local vector of observations + Array shape: (dim_obs) + resid : ndarray[np.float64, ndim=1] + Input vector of residuum + Array shape: (dim_obs) + + Returns + ------- + lhood : double + Output vector - log likelihood + """ + cdef double lhood + with nogil: + c__pdafomi_likelihood_cb(&step, &dim_obs, &obs[0], &resid[0], &lhood) + + return lhood + + +def add_obs_error_cb(int step, int dim_obs_p, double [::1,:] c_p): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_obs_p : int + Dimension of PE-local observation vector + c_p : ndarray[np.float64, ndim=2] + Matrix to which R is added + Array shape: (dim_obs_p,dim_obs_p) + + Returns + ------- + c_p : ndarray[np.float64, ndim=2] + Matrix to which R is added + Array shape: (dim_obs_p,dim_obs_p) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] c_p_np = np.asarray(c_p, dtype=np.float64, order="F") + with nogil: + c__pdafomi_add_obs_error_cb(&step, &dim_obs_p, &c_p[0,0]) + + return c_p_np + + +def init_obscovar_cb(int step, int dim_obs, int dim_obs_p, + double [::1] m_state_p): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_obs : int + Dimension of observation vector + dim_obs_p : int + PE-local dimension of obs. vector + m_state_p : ndarray[np.float64, ndim=1] + Observation vector + Array shape: (dim_obs_p) + + Returns + ------- + covar : ndarray[np.float64, ndim=2] + Observation error covar. matrix + Array shape: (dim_obs,dim_obs) + isdiag : bint + Whether matrix R is diagonal + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] covar_np = np.zeros((dim_obs,dim_obs), dtype=np.float64, order="F") + cdef double [::1,:] covar = covar_np + cdef bint isdiag + with nogil: + c__pdafomi_init_obscovar_cb(&step, &dim_obs, &dim_obs_p, + &covar[0,0], &m_state_p[0], &isdiag) + + return covar_np, isdiag + + +def init_obserr_f_cb(int step, int dim_obs_f, double [::1] obs_f): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_obs_f : int + Full dimension of observation vector + obs_f : ndarray[np.float64, ndim=1] + Full observation vector + Array shape: (dim_obs_f) + + Returns + ------- + obserr_f : ndarray[np.float64, ndim=1] + Full observation error stddev + Array shape: (dim_obs_f) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obserr_f_np = np.zeros((dim_obs_f), dtype=np.float64, order="F") + cdef double [::1] obserr_f = obserr_f_np + with nogil: + c__pdafomi_init_obserr_f_cb(&step, &dim_obs_f, &obs_f[0], &obserr_f[0]) + + return obserr_f_np + + +def localize_covar_cb(int dim_p, int dim_obs, double [::1,:] hp_p, + double [::1,:] hph): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_p : int + Process-local state dimension + dim_obs : int + Number of observations + hp_p : ndarray[np.float64, ndim=2] + Process-local part of matrix HP + Array shape: (dim_obs, dim_p) + hph : ndarray[np.float64, ndim=2] + Matrix HPH + Array shape: (dim_obs, dim_obs) + + Returns + ------- + hp_p : ndarray[np.float64, ndim=2] + Process-local part of matrix HP + Array shape: (dim_obs, dim_p) + hph : ndarray[np.float64, ndim=2] + Matrix HPH + Array shape: (dim_obs, dim_obs) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hp_p_np = np.asarray(hp_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hph_np = np.asarray(hph, dtype=np.float64, order="F") + with nogil: + c__pdafomi_localize_covar_cb(&dim_p, &dim_obs, &hp_p[0,0], &hph[0,0]) + + return hp_p_np, hph_np + + +def localize_covar_serial_cb(int iobs, int dim_p, int dim_obs, + double [::1] hp_p, double [::1] hxy_p): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + iobs : int + Index of current observation + dim_p : int + Process-local state dimension + dim_obs : int + Number of observations + hp_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HP for observation iobs + Array shape: (dim_p) + hxy_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HX(HX_all) for full observations + Array shape: (dim_obs) + + Returns + ------- + hp_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HP for observation iobs + Array shape: (dim_p) + hxy_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HX(HX_all) for full observations + Array shape: (dim_obs) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] hp_p_np = np.asarray(hp_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] hxy_p_np = np.asarray(hxy_p, dtype=np.float64, order="F") + with nogil: + c__pdafomi_localize_covar_serial_cb(&iobs, &dim_p, &dim_obs, + &hp_p[0], &hxy_p[0]) + + return hp_p_np, hxy_p_np + + +def omit_by_inno_l_cb(int domain_p, int dim_obs_l, double [::1] resid_l, + double [::1] obs_l): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + dim_obs_l : int + PE-local dimension of obs. vector + resid_l : ndarray[np.float64, ndim=1] + Input vector of residuum + Array shape: (dim_obs_l) + obs_l : ndarray[np.float64, ndim=1] + Input vector of local observations + Array shape: (dim_obs_l) + + Returns + ------- + resid_l : ndarray[np.float64, ndim=1] + Input vector of residuum + Array shape: (dim_obs_l) + obs_l : ndarray[np.float64, ndim=1] + Input vector of local observations + Array shape: (dim_obs_l) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] resid_l_np = np.asarray(resid_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obs_l_np = np.asarray(obs_l, dtype=np.float64, order="F") + with nogil: + c__pdafomi_omit_by_inno_l_cb(&domain_p, &dim_obs_l, &resid_l[0], + &obs_l[0]) + + return resid_l_np, obs_l_np + + +def omit_by_inno_cb(int dim_obs_f, double [::1] resid_f, double [::1] obs_f): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_obs_f : int + Full dimension of obs. vector + resid_f : ndarray[np.float64, ndim=1] + Input vector of residuum + Array shape: (dim_obs_f) + obs_f : ndarray[np.float64, ndim=1] + Input vector of full observations + Array shape: (dim_obs_f) + + Returns + ------- + resid_f : ndarray[np.float64, ndim=1] + Input vector of residuum + Array shape: (dim_obs_f) + obs_f : ndarray[np.float64, ndim=1] + Input vector of full observations + Array shape: (dim_obs_f) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] resid_f_np = np.asarray(resid_f, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obs_f_np = np.asarray(obs_f, dtype=np.float64, order="F") + with nogil: + c__pdafomi_omit_by_inno_cb(&dim_obs_f, &resid_f[0], &obs_f[0]) + + return resid_f_np, obs_f_np diff --git a/pyPDAF/source/src/pyPDAF/PDAF/diag.pxd b/pyPDAF/source/src/pyPDAF/PDAF/diag.pxd new file mode 100644 index 0000000000000000000000000000000000000000..f18d7e68ada8be0e5f05f9a425a38c05786d85f1 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/diag.pxd @@ -0,0 +1,58 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t +cdef extern void c__pdaf_diag_ensmean(int* dim, int* dim_ens, + double* state, double* ens, int* status) noexcept nogil; + +cdef extern void c__pdaf_diag_stddev_nompi(int* dim, int* dim_ens, + double* state, double* ens, double* stddev, int* do_mean, + int* status) noexcept nogil; + +cdef extern void c__pdaf_diag_stddev(int* dim_p, int* dim_ens, + double* state_p, double* ens_p, double* stddev_g, int* do_mean, + int* comm_filter, int* status) noexcept nogil; + +cdef extern void c__pdaf_diag_variance_nompi(int* dim, int* dim_ens, + double* state, double* ens, double* variance, double* stddev, + int* do_mean, int* do_stddev, int* status) noexcept nogil; + +cdef extern void c__pdaf_diag_variance(int* dim_p, int* dim_ens, + double* state_p, double* ens_p, double* variance_p, double* stddev_g, + int* do_mean, int* do_stddev, int* comm_filter, + int* status) noexcept nogil; + +cdef extern void c__pdaf_diag_rmsd_nompi(int* dim_p, double* statea_p, + double* stateb_p, double* rmsd_p, + int* status) noexcept nogil; + +cdef extern void c__pdaf_diag_rmsd(int* dim_p, double* statea_p, + double* stateb_p, double* rmsd_g, int* comm_filter, + int* status) noexcept nogil; + +cdef extern void c__pdaf_diag_crps_mpi(int* dim_p, int* dim_ens, + int* element, double* oens, double* obs, int* comm_filter, + int* mype_filter, int* npes_filter, double* crps, double* reli, + double* pot_crps, double* uncert, + int* status) noexcept nogil; + +cdef extern void c__pdaf_diag_crps_nompi(int* dim, int* dim_ens, + int* element, double* oens, double* obs, double* crps, double* reli, + double* resol, double* uncert, int* status) noexcept nogil; + +cdef extern void c__pdaf_diag_effsample(int* dim_sample, double* weights, + double* n_eff) noexcept nogil; + +cdef extern void c__pdaf_diag_ensstats(int* dim, int* dim_ens, + int* element, double* state, double* ens, double* skewness, + double* kurtosis, int* status) noexcept nogil; + +cdef extern void c__pdaf_diag_compute_moments(int* dim_p, int* dim_ens, + double* ens, int* kmax, double* moments, + int* bias) noexcept nogil; + +cdef extern void c__pdaf_diag_histogram(int* ncall, int* dim, int* dim_ens, + int* element, double* state, double* ens, int* hist, double* delta, + int* status) noexcept nogil; + +cdef extern void c__pdaf_diag_reliability_budget(int* n_times, + int* dim_ens, int* dim_p, double* ens_p, double* obsvar, double* obs_p, + double* budget, double* bias_2) noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/PDAF/diag.pyi b/pyPDAF/source/src/pyPDAF/PDAF/diag.pyi new file mode 100644 index 0000000000000000000000000000000000000000..01fae69cb1603e380e9dc8e8f0d5b0688c1971d0 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/diag.pyi @@ -0,0 +1,609 @@ +# pylint: disable=unused-argument +import numpy as np +from typing import Tuple + +def diag_ensmean( + dim: int, + dim_ens: int, + state: np.ndarray, + ens: np.ndarray +) -> Tuple[np.ndarray, int]: + r"""Compute the ensemble mean of the state ensemble. + + Parameters + ---------- + dim : int + State dimension. + dim_ens : int + Ensemble size. + state : ndarray[np.float64, ndim=1], shape (dim,) + State vector. + ens : ndarray[np.float64, ndim=2], shape (dim, dim_ens) + State ensemble. + + Returns + ------- + state : ndarray[np.float64, ndim=1], shape (dim,) + State vector (ensemble mean). + status : int + Status flag (0=success). + """ + +def diag_stddev_nompi( + dim: int, + dim_ens: int, + state: np.ndarray, + ens: np.ndarray, + do_mean: int +) -> Tuple[np.ndarray, float, int]: + r"""Compute ensemble standard deviation and ensemble mean without MPI. + + Parameters + ---------- + dim : int + state dimension + dim_ens : int + Ensemble size + state : ndarray[np.float64, ndim=1] + State vector + Array shape: (dim) + ens : ndarray[np.float64, ndim=2] + State ensemble + Array shape: (dim, dim_ens) + do_mean : int + Whether to compute ensemble mean + + Returns + ------- + state : ndarray[np.float64, ndim=1] + State vector + Array shape: (dim) + stddev : double + Standard deviation of ensemble + status : int + Status flag (0=success) + """ + +def diag_stddev( + dim_p: int, + dim_ens: int, + state_p: np.ndarray, + ens_p: np.ndarray, + do_mean: int, + comm_filter: int +) -> Tuple[np.ndarray, float, int]: + r"""Compute ensemble standard deviation and ensemble mean. + + Parameters + ---------- + dim_p : int + state dimension + dim_ens : int + Ensemble size + state_p : ndarray[np.float64, ndim=1] + State vector + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + State ensemble + Array shape: (dim_p, dim_ens) + do_mean : int + Whether to compute ensemble mean + comm_filter : int + Filter communicator + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + State vector + Array shape: (dim_p) + stddev_g : double + Global mean standard deviation of ensemble + status : int + Status flag (0=success) + """ + +def diag_variance_nompi( + dim: int, + dim_ens: int, + state: np.ndarray, + ens: np.ndarray, + do_mean: int, + do_stddev: int +) -> Tuple[np.ndarray, np.ndarray, float, int]: + r"""Compute ensemble variance/standard deviation and mean without MPI. + + Parameters + ---------- + dim : int + state dimension + dim_ens : int + Ensemble size + state : ndarray[np.float64, ndim=1] + State vector + Array shape: (dim) + ens : ndarray[np.float64, ndim=2] + State ensemble + Array shape: (dim, dim_ens) + do_mean : int + Whether to compute ensemble mean + do_stddev : int + Whether to compute the ensemble mean standard deviation + + Returns + ------- + state : ndarray[np.float64, ndim=1] + State vector + Array shape: (dim) + variance : ndarray[np.float64, ndim=1] + Variance state vector + Array shape: (dim) + stddev : double + Standard deviation of ensemble + status : int + Status flag (0=success) + """ + +def diag_variance( + dim_p: int, + dim_ens: int, + state_p: np.ndarray, + ens_p: np.ndarray, + do_mean: int, + do_stddev: int, + comm_filter: int +) -> Tuple[np.ndarray, np.ndarray, float, int]: + r"""Compute ensemble variance/standard deviation and mean. + + Parameters + ---------- + dim_p : int + state dimension + dim_ens : int + Ensemble size + state_p : ndarray[np.float64, ndim=1] + State vector + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + State ensemble + Array shape: (dim_p, dim_ens) + do_mean : int + Whether to compute ensemble mean + do_stddev : int + Whether to compute the ensemble mean standard deviation + comm_filter : int + Filter communicator + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + State vector + Array shape: (dim_p) + variance_p : ndarray[np.float64, ndim=1] + Variance state vector + Array shape: (dim_p) + stddev_g : double + Global standard deviation of ensemble + status : int + Status flag (0=success) + """ + +def diag_rmsd_nompi( + dim_p: int, + statea_p: np.ndarray, + stateb_p: np.ndarray +) -> Tuple[float, int]: + r"""Compute the root mean squared distance between two vectors without MPI. + + Parameters + ---------- + dim_p : int + state dimension + statea_p : ndarray[np.float64, ndim=1] + State vector A + Array shape: (dim_p) + stateb_p : ndarray[np.float64, ndim=1] + State vector B + Array shape: (dim_p) + + Returns + ------- + rmsd_p : double + RSMD + status : int + Status flag (0=success) + """ + +def diag_rmsd( + dim_p: int, + statea_p: np.ndarray, + stateb_p: np.ndarray, + comm_filter: int +) -> Tuple[float, int]: + r"""Compute the root mean squared distance between two vectors. + + Parameters + ---------- + dim_p : int + state dimension + statea_p : ndarray[np.float64, ndim=1] + State vector A + Array shape: (dim_p) + stateb_p : ndarray[np.float64, ndim=1] + State vector B + Array shape: (dim_p) + comm_filter : int + Filter communicator + + Returns + ------- + rmsd_g : double + Global RSMD + status : int + Status flag (0=success) + """ + +def diag_crps_mpi( + dim_p: int, + dim_ens: int, + element: int, + oens: np.ndarray, + obs: np.ndarray, + comm_filter: int, + mype_filter:int, + npes_filter:int +) -> Tuple[float, float, float, float, int]: + r"""Obtain a continuous rank probability score for an ensemble. + + The implementation is based on [1]_. + + References + ---------- + .. [1] Hersbach, H. (2000), + Decomposition of the Continuous Ranked Probability + Score for + Ensemble Prediction Systems, + Wea. Forecasting, 15, 559–570, + doi:10.1175/1520-0434(2000)015<0559:DOTCRP>2.0.CO;2 + + Parameters + ---------- + dim_p: int + Dimension of state vector + dim_ens: int + Ensemble size + element : int + ID of element to be used. If element=0, mean values over all elements are computed + oens : ndarray[tuple[dim, dim_ens, ...], np.float64] + State ensemble. shape: (dim_p, dim_ens) + obs : ndarray[tuple[dim, ...], np.float64] + State ensemble. shape: (dim_p) + comm_filter : int + MPI communicator for filter + mype_filter : int + rank of MPI communicator + npes_filter : int + size of MPI communicator + + Returns + ------- + CRPS : float + CRPS + reli : float + Reliability + resol : float + resolution + uncert : float + uncertainty + status : int + Status flag (0=success) + """ + +def diag_crps_nompi( + dim: int, + dim_ens: int, + element: int, + oens: np.ndarray, + obs: np.ndarray +) -> Tuple[float, float, float, float, int]: + r"""Obtain a continuous rank probability score for an ensemble without MPI. + + The implementation is based on [1]_. + + References + ---------- + .. [1] Hersbach, H. (2000), + Decomposition of the Continuous Ranked Probability + Score for + Ensemble Prediction Systems, + Wea. Forecasting, 15, 559–570, + doi:10.1175/1520-0434(2000)015<0559:DOTCRP>2.0.CO;2 + + Parameters + ---------- + dim_p: int + Dimension of state vector + dim_ens: int + Ensemble size + element : int + ID of element to be used. If element=0, mean values over all elements are computed + oens : ndarray[tuple[dim, dim_ens, ...], np.float64] + State ensemble. shape: (dim_p, dim_ens) + obs : ndarray[tuple[dim, ...], np.float64] + State ensemble. shape: (dim_p) + + Returns + ------- + CRPS : float + CRPS + reli : float + Reliability + resol : float + resolution + uncert : float + uncertainty + status : int + Status flag (0=success) + """ + +def diag_effsample( + dim_sample: int, + weights: np.ndarray +) -> float: + r"""Calculating the effective sample size of a particle filter. + + Based on [1]_, it is defined as the + inverse of the sum of the squared particle filter weights: + :math:`N_{eff} = \frac{1}{\sum_{i=1}^{N} w_i^2}` + where :math:`w_i` is the weight of particle with index i. + and :math:`N` is the number of particles. + + If the :math:`N_{eff}=N`, all weights are identical, + and the filter has no influence on the analysis. + If :math:`N_{eff}=0`, the filter is collapsed. + + This is typically called during the analysis step + of a particle filter, + e.g. in the analysis step of NETF and LNETF. + + References + ---------- + .. [1] Doucet, A., de Freitas, N., Gordon, N. (2001). + An Introduction to Sequential Monte Carlo Methods. + In: Doucet, A., de Freitas, N., Gordon, N. (eds) + Sequential Monte Carlo Methods in Practice. + Statistics for Engineering and Information Science. + Springer, New York, NY. + https://doi.org/10.1007/978-1-4757-3437-9_1 + + Parameters + ---------- + dim_sample : int + Sample size + weights : ndarray[np.float64, ndim=1] + Weights of the samples + Array shape: (dim_sample) + + Returns + ------- + n_eff : double + Effecfive sample size + """ + +def diag_ensstats( + dim: int, + dim_ens: int, + element: int, + state: np.ndarray, + ens: np.ndarray +) -> Tuple[float, float, int]: + r"""Computing the skewness and kurtosis of + the ensemble of a given element of the state vector. + + The definition used for kurtosis follows that used by [1]_. + + References + ---------- + .. [1] Lawson, W. G., & Hansen, J. A. (2004). + Implications of stochastic and deterministic + filters as ensemble-based + data assimilation methods in varying regimes + of error growth. + Monthly weather review, 132(8), 1966-1981. + + Parameters + ---------- + dim : int + PE-local state dimension + dim_ens : int + Ensemble size + element : int + ID of element to be used + state : ndarray[np.float64, ndim=1] + State vector + Array shape: (dim) + ens : ndarray[np.float64, ndim=2] + State ensemble + Array shape: (dim, dim_ens) + + Returns + ------- + skewness : double + Skewness of ensemble + kurtosis : double + Kurtosis of ensemble + status : int + Status flag (0=success) + """ + +def diag_compute_moments( + dim_p: int, + dim_ens: int, + ens: np.ndarray, + kmax: int, + bias: int +) -> np.ndarray: + r"""Computes the mean, the unbiased variance, the unbiased skewness, + and the unbiased excess kurtosis from an ensemble. + + Parameters + ---------- + dim_p : int + local size of the state + dim_ens : int + number of ensemble members/samples + ens : ndarray[np.float64, ndim=2] + ensemble matrix + Array shape: (dim_p,dim_ens) + kmax : int + maximum order of central moment that is computed, maximum is 4 + bias : int + if 0 bias correction is applied (default) + otherwise, no bias correction + + Returns + ------- + moments : ndarray[np.float64, ndim=2] + The columns contain the moments of the ensemble + - column 0: mean + - column 1: variance + - column 2: skewness + - column 3: excess kurtosis + Array shape: (dim_p, kmax) + """ + +def diag_histogram( + ncall: int, + dim: int, + dim_ens: int, + element: int, + state: np.ndarray, + ens: np.ndarray, + hist: np.ndarray +) -> Tuple[np.ndarray, float, int]: + r"""Computing the rank histogram of an ensemble. + + A rank histogram is used to diagnose + the reliability of the ensemble [1]_. + A perfectly reliable ensemble should have + a uniform rank histogram. + + The function can be called in the + pre/poststep routine of PDAF + both before and after the analysis step + to collect the histogram information. + + References + ---------- + .. [1] Hamill, T. M. (2001). + Interpretation of rank histograms + for verifying ensemble forecasts. + Monthly Weather Review, 129(3), 550-560. + + Parameters + ---------- + ncall : int + Number of calls to routine + dim : int + State dimension + dim_ens : int + Ensemble size + element : int + Element of vector used for histogram + state : ndarray[np.float64, ndim=1] + State vector + Array shape: (dim) + ens : ndarray[np.float64, ndim=2] + State ensemble + Array shape: (dim, dim_ens) + hist : ndarray[np.intc, ndim=1] + Histogram about the state + Array shape: (dim_ens+1) + + Returns + ------- + hist : ndarray[np.intc, ndim=1] + Histogram about the state + Array shape: (dim_ens+1) + delta : double + deviation measure from flat histogram + status : int + Status flag (0=success) + """ + +def diag_reliability_budget( + n_times: int, + dim_ens: int, + dim_p: int, + ens_p: np.ndarray, + obsvar: np.ndarray, + obs_p: np.ndarray +) -> Tuple[np.ndarray, np.ndarray]: + r"""Compute ensemble reliability budget + + The diagnostics derives a balance relationship that decomposes the + departure between the ensemble mean and observations: + Depar^2 = Bias^2 + EnsVar + ObsUnc^2 + Residual + under the assumption of a perfectly reliable ensemble [1]_. When the + residual term is not small, one can identify the sources of + problematic ensemble representation of the uncertainty by looking at + each terms. One of the benefits of + the reliability budget diagnostics is that it can identify spatially + local issues in ensemble perturbations. + + In this subroutine, the budget array returns each term of the + reliability budget is given at each given time step. The returned + array can be used for significant t-test where each time step is used + as a sample from the population. The actual budget is the mean over + time steps except for Bias^2 term, which is given separately. This + is because the unsquared bias is used in the t-test in the original + paper. + + The subroutine does not comes with a t-test to ensure that + the reliability budget is statistically significant as done + in the original paper. However, this can be achieved with external + libraries or software if the t-test is deemed important. The t-test + should account for the temporal autocorrelation between time steps + in the given trajectory. + + The diagnostics requires a trajectory of ensemble and observations, + a trajectory of an ensemle of observation error variances. The + ensemble of observation error variances can be the square of + observation errors sampled from observation error distribution as + done in stochastic ensemble Kalman filter. In deterministic ensemble + systems, the ensemble of observation error variances can be the + observation error variances where each ensemble member has the same + value. + + References + ---------- + .. [1] Rodwell, M. J., Lang, S. T. K., Ingleby, N. B., Bormann, N., Holm, + E., Rabier, F., ... & Yamaguchi, M. (2016). Reliability in ensemble data assimilation. + Quarterly Journal of the Royal Meteorological Society, 142(694), 443-454. + + Parameters + ---------- + n_times : int + Number of time steps + dim_ens : int + Number of ensemble members + dim_p : int + Dimension of the state vector + ens_p : ndarray[np.float64, ndim=3] + Ensemble matrix over times + Array shape: (dim_p, dim_ens, n_times) + obsvar : ndarray[np.float64, ndim=3] + Squared observation error/variance at n_times + Array shape: (dim_p, dim_ens, n_times) + obs_p : ndarray[np.float64, ndim=2] + Observation vector + Array shape: (dim_p, n_times) + + Returns + ------- + budget : ndarray[np.float64, ndim=3] + Budget term for a single time step + Array shape: (dim_p, n_times, 5) + bias_2 : ndarray[np.float64, ndim=1] + bias^2 uses + Array shape: (dim_p) + """ \ No newline at end of file diff --git a/pyPDAF/source/src/pyPDAF/PDAF/diag.pyx b/pyPDAF/source/src/pyPDAF/PDAF/diag.pyx new file mode 100644 index 0000000000000000000000000000000000000000..5d8143e2ad75adc32fc9d1ca44ca2e411a686b1d --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/diag.pyx @@ -0,0 +1,696 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + +def diag_ensmean(int dim, int dim_ens, double [::1] state, + double [::1,:] ens): + r"""diag_ensmean(dim: int, dim_ens: int,state: np.ndarray,ens: np.ndarray) -> Tuple[np.ndarray, int] + + Compute the ensemble mean of the state ensemble. + + Parameters + ---------- + dim : int + State dimension. + dim_ens : int + Ensemble size. + state : ndarray[np.float64, ndim=1], shape (dim,) + State vector. + ens : ndarray[np.float64, ndim=2], shape (dim, dim_ens) + State ensemble. + + Returns + ------- + state : ndarray[np.float64, ndim=1], shape (dim,) + State vector (ensemble mean). + status : int + Status flag (0=success). + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_np = np.asarray(state, dtype=np.float64, order="F") + cdef int status + with nogil: + c__pdaf_diag_ensmean(&dim, &dim_ens, &state[0], &ens[0,0], &status) + + return state_np, status + + +def diag_stddev_nompi(int dim, int dim_ens, double [::1] state, + double [::1,:] ens, int do_mean): + r"""diag_stddev_nompi(dim: int,dim_ens: int,state: np.ndarray,ens: np.ndarray,do_mean: int) -> Tuple[np.ndarray, float, int] + + Compute ensemble standard deviation and ensemble mean without MPI. + + Parameters + ---------- + dim : int + state dimension + dim_ens : int + Ensemble size + state : ndarray[np.float64, ndim=1] + State vector + Array shape: (dim) + ens : ndarray[np.float64, ndim=2] + State ensemble + Array shape: (dim, dim_ens) + do_mean : int + Whether to compute ensemble mean + + Returns + ------- + state : ndarray[np.float64, ndim=1] + State vector + Array shape: (dim) + stddev : double + Standard deviation of ensemble + status : int + Status flag (0=success) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_np = np.asarray(state, dtype=np.float64, order="F") + cdef double stddev + cdef int status + with nogil: + c__pdaf_diag_stddev_nompi(&dim, &dim_ens, &state[0], &ens[0,0], + &stddev, &do_mean, &status) + + return state_np, stddev, status + + +def diag_stddev(int dim_p, int dim_ens, double [::1] state_p, + double [::1,:] ens_p, int do_mean, int comm_filter): + r"""diag_stddev(dim_p: int, dim_ens: int, state_p: np.ndarray, ens_p: np.ndarray, do_mean: int,comm_filter: int) -> Tuple[np.ndarray, float, int] + + Compute ensemble standard deviation and ensemble mean. + + Parameters + ---------- + dim_p : int + state dimension + dim_ens : int + Ensemble size + state_p : ndarray[np.float64, ndim=1] + State vector + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + State ensemble + Array shape: (dim_p, dim_ens) + do_mean : int + Whether to compute ensemble mean + comm_filter : int + Filter communicator + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + State vector + Array shape: (dim_p) + stddev_g : double + Global mean standard deviation of ensemble + status : int + Status flag (0=success) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef double stddev_g + cdef int status + with nogil: + c__pdaf_diag_stddev(&dim_p, &dim_ens, &state_p[0], &ens_p[0,0], + &stddev_g, &do_mean, &comm_filter, &status) + + return state_p_np, stddev_g, status + + +def diag_variance_nompi(int dim, int dim_ens, double [::1] state, + double [::1,:] ens, int do_mean, int do_stddev): + r"""diag_variance_nompi(dim: int, dim_ens: int, state: np.ndarray, ens: np.ndarray, do_mean: int, do_stddev: int) -> Tuple[np.ndarray, np.ndarray, float, int] + + Compute ensemble variance/standard deviation and mean without MPI. + + Parameters + ---------- + dim : int + state dimension + dim_ens : int + Ensemble size + state : ndarray[np.float64, ndim=1] + State vector + Array shape: (dim) + ens : ndarray[np.float64, ndim=2] + State ensemble + Array shape: (dim, dim_ens) + do_mean : int + Whether to compute ensemble mean + do_stddev : int + Whether to compute the ensemble mean standard deviation + + Returns + ------- + state : ndarray[np.float64, ndim=1] + State vector + Array shape: (dim) + variance : ndarray[np.float64, ndim=1] + Variance state vector + Array shape: (dim) + stddev : double + Standard deviation of ensemble + status : int + Status flag (0=success) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_np = np.asarray(state, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] variance_np = np.zeros((dim), dtype=np.float64, order="F") + cdef double [::1] variance = variance_np + cdef double stddev + cdef int status + with nogil: + c__pdaf_diag_variance_nompi(&dim, &dim_ens, &state[0], &ens[0,0], + &variance[0], &stddev, &do_mean, + &do_stddev, &status) + + return state_np, variance_np, stddev, status + + +def diag_variance(int dim_p, int dim_ens, double [::1] state_p, + double [::1,:] ens_p, int do_mean, int do_stddev, int comm_filter): + r"""diag_variance(dim_p: int, dim_ens: int, state_p: np.ndarray, ens_p: np.ndarray, do_mean: int, do_stddev: int, comm_filter: int) -> Tuple[np.ndarray, np.ndarray, float, int] + + Compute ensemble variance/standard deviation and mean. + + Parameters + ---------- + dim_p : int + state dimension + dim_ens : int + Ensemble size + state_p : ndarray[np.float64, ndim=1] + State vector + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + State ensemble + Array shape: (dim_p, dim_ens) + do_mean : int + Whether to compute ensemble mean + do_stddev : int + Whether to compute the ensemble mean standard deviation + comm_filter : int + Filter communicator + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + State vector + Array shape: (dim_p) + variance_p : ndarray[np.float64, ndim=1] + Variance state vector + Array shape: (dim_p) + stddev_g : double + Global standard deviation of ensemble + status : int + Status flag (0=success) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] variance_p_np = np.zeros((dim_p), dtype=np.float64, order="F") + cdef double [::1] variance_p = variance_p_np + cdef double stddev_g + cdef int status + with nogil: + c__pdaf_diag_variance(&dim_p, &dim_ens, &state_p[0], &ens_p[0,0], + &variance_p[0], &stddev_g, &do_mean, + &do_stddev, &comm_filter, &status) + + return state_p_np, variance_p_np, stddev_g, status + + +def diag_rmsd_nompi(int dim_p, double [::1] statea_p, double [::1] stateb_p): + r"""diag_rmsd_nompi(dim_p: int, statea_p: np.ndarray, stateb_p: np.ndarray) -> Tuple[float, int] + + Compute the root mean squared distance between two vectors without MPI. + + Parameters + ---------- + dim_p : int + state dimension + statea_p : ndarray[np.float64, ndim=1] + State vector A + Array shape: (dim_p) + stateb_p : ndarray[np.float64, ndim=1] + State vector B + Array shape: (dim_p) + + Returns + ------- + rmsd_p : double + RSMD + status : int + Status flag (0=success) + """ + cdef double rmsd_p + cdef int status + with nogil: + c__pdaf_diag_rmsd_nompi(&dim_p, &statea_p[0], &stateb_p[0], + &rmsd_p, &status) + + return rmsd_p, status + + +def diag_rmsd(int dim_p, double [::1] statea_p, double [::1] stateb_p, + int comm_filter): + r"""diag_rmsd(dim_p: int, statea_p: np.ndarray, stateb_p: np.ndarray, comm_filter: int) -> Tuple[float, int] + + Compute the root mean squared distance between two vectors. + + Parameters + ---------- + dim_p : int + state dimension + statea_p : ndarray[np.float64, ndim=1] + State vector A + Array shape: (dim_p) + stateb_p : ndarray[np.float64, ndim=1] + State vector B + Array shape: (dim_p) + comm_filter : int + Filter communicator + + Returns + ------- + rmsd_g : double + Global RSMD + status : int + Status flag (0=success) + """ + cdef double rmsd_g + cdef int status + with nogil: + c__pdaf_diag_rmsd(&dim_p, &statea_p[0], &stateb_p[0], &rmsd_g, + &comm_filter, &status) + + return rmsd_g, status + +def diag_crps_mpi(int dim_p, int dim_ens, int element, + double [::1,:] oens, double [::1] obs, int comm_filter, + int mype_filter, int npes_filter): + r"""diag_crps_mpi(dim_p: int, dim_ens: int, element: int, oens: np.ndarray, obs: np.ndarray, comm_filter: int, mype_filter:int, npes_filter:int) -> Tuple[float, float, float, float, int] + + Obtain a continuous rank probability score for an ensemble. + + The implementation is based on [1]_. + + References + ---------- + .. [1] Hersbach, H. (2000), + Decomposition of the Continuous Ranked Probability + Score for + Ensemble Prediction Systems, + Wea. Forecasting, 15, 559–570, + doi:10.1175/1520-0434(2000)015<0559:DOTCRP>2.0.CO;2 + + Parameters + ---------- + dim_p: int + Dimension of state vector + dim_ens: int + Ensemble size + element : int + ID of element to be used. If element=0, mean values over all elements are computed + oens : ndarray[tuple[dim, dim_ens, ...], np.float64] + State ensemble. shape: (dim_p, dim_ens) + obs : ndarray[tuple[dim, ...], np.float64] + State ensemble. shape: (dim_p) + comm_filter : int + MPI communicator for filter + mype_filter : int + rank of MPI communicator + npes_filter : int + size of MPI communicator + + Returns + ------- + crps : double + CRPS + reli : double + Reliability + pot_crps : double + potential CRPS + uncert : double + uncertainty + status : int + Status flag (0=success) + """ + cdef double crps + cdef double reli + cdef double pot_crps + cdef double uncert + cdef int status + with nogil: + c__pdaf_diag_crps_mpi(&dim_p, &dim_ens, &element, &oens[0,0], + &obs[0], &comm_filter, &mype_filter, + &npes_filter, &crps, &reli, &pot_crps, + &uncert, &status) + + return crps, reli, pot_crps, uncert, status + +def diag_crps_nompi(int dim, int dim_ens, int element, + double [::1,:] oens, double [::1] obs): + r"""diag_crps_nompi(dim: int, dim_ens: int, element: int, oens: np.ndarray, obs: np.ndarray) -> Tuple[float, float, float, float, int] + + Obtain a continuous rank probability score for an ensemble without MPI. + + The implementation is based on [1]_. + + References + ---------- + .. [1] Hersbach, H. (2000), + Decomposition of the Continuous Ranked Probability + Score for + Ensemble Prediction Systems, + Wea. Forecasting, 15, 559–570, + doi:10.1175/1520-0434(2000)015<0559:DOTCRP>2.0.CO;2 + + Parameters + ---------- + dim_p: int + Dimension of state vector + dim_ens: int + Ensemble size + element : int + ID of element to be used. If element=0, mean values over all elements are computed + oens : ndarray[tuple[dim, dim_ens, ...], np.float64] + State ensemble. shape: (dim_p, dim_ens) + obs : ndarray[tuple[dim, ...], np.float64] + State ensemble. shape: (dim_p) + + Returns + ------- + CRPS : float + CRPS + reli : float + Reliability + resol : float + resolution + uncert : float + uncertainty + status : int + Status flag (0=success) + """ + cdef double crps + cdef double reli + cdef double resol + cdef double uncert + cdef int status + with nogil: + c__pdaf_diag_crps_nompi(&dim, &dim_ens, &element, &oens[0,0], + &obs[0], &crps, &reli, &resol, &uncert, &status) + + return crps, reli, resol, uncert, status + + +def diag_effsample(int dim_sample, double [::1] weights): + r"""diag_effsample(dim_sample: int, weights: np.ndarray) -> float + + Calculating the effective sample size of a particle filter. + + Based on [1]_, it is defined as the + inverse of the sum of the squared particle filter weights: + :math:`N_{eff} = \frac{1}{\sum_{i=1}^{N} w_i^2}` + where :math:`w_i` is the weight of particle with index i. + and :math:`N` is the number of particles. + + If the :math:`N_{eff}=N`, all weights are identical, + and the filter has no influence on the analysis. + If :math:`N_{eff}=0`, the filter is collapsed. + + This is typically called during the analysis step + of a particle filter, + e.g. in the analysis step of NETF and LNETF. + + References + ---------- + .. [1] Doucet, A., de Freitas, N., Gordon, N. (2001). + An Introduction to Sequential Monte Carlo Methods. + In: Doucet, A., de Freitas, N., Gordon, N. (eds) + Sequential Monte Carlo Methods in Practice. + Statistics for Engineering and Information Science. + Springer, New York, NY. + https://doi.org/10.1007/978-1-4757-3437-9_1 + + Parameters + ---------- + dim_sample : int + Sample size + weights : ndarray[np.float64, ndim=1] + Weights of the samples + Array shape: (dim_sample) + + Returns + ------- + n_eff : double + Effecfive sample size + """ + cdef double n_eff + with nogil: + c__pdaf_diag_effsample(&dim_sample, &weights[0], &n_eff) + + return n_eff + + +def diag_ensstats(int dim, int dim_ens, int element, double [::1] state, + double [::1,:] ens): + r"""diag_ensstats(dim: int, dim_ens: int, element: int, state: np.ndarray, ens: np.ndarray) -> Tuple[float, float, int] + + Computing the skewness and kurtosis of + the ensemble of a given element of the state vector. + + The definition used for kurtosis follows that used by [1]_. + + References + ---------- + .. [1] Lawson, W. G., & Hansen, J. A. (2004). + Implications of stochastic and deterministic + filters as ensemble-based + data assimilation methods in varying regimes + of error growth. + Monthly weather review, 132(8), 1966-1981. + + Parameters + ---------- + dim : int + PE-local state dimension + dim_ens : int + Ensemble size + element : int + ID of element to be used + state : ndarray[np.float64, ndim=1] + State vector + Array shape: (dim) + ens : ndarray[np.float64, ndim=2] + State ensemble + Array shape: (dim, dim_ens) + + Returns + ------- + skewness : double + Skewness of ensemble + kurtosis : double + Kurtosis of ensemble + status : int + Status flag (0=success) + """ + cdef double skewness + cdef double kurtosis + cdef int status + with nogil: + c__pdaf_diag_ensstats(&dim, &dim_ens, &element, &state[0], + &ens[0,0], &skewness, &kurtosis, &status) + + return skewness, kurtosis, status + + +def diag_compute_moments(int dim_p, int dim_ens, double [::1,:] ens, + int kmax, int bias): + r"""diag_compute_moments(dim_p: int, dim_ens: int, ens: np.ndarray, kmax: int, bias: int) -> np.ndarray + + Computes the mean, the unbiased variance, the unbiased skewness, + and the unbiased excess kurtosis from an ensemble. + + Parameters + ---------- + dim_p : int + local size of the state + dim_ens : int + number of ensemble members/samples + ens : ndarray[np.float64, ndim=2] + ensemble matrix + Array shape: (dim_p,dim_ens) + kmax : int + maximum order of central moment that is computed, maximum is 4 + bias : int + if 0 bias correction is applied (default) + otherwise, no bias correction + + Returns + ------- + moments : ndarray[np.float64, ndim=2] + The columns contain the moments of the ensemble + - column 0: mean + - column 1: variance + - column 2: skewness + - column 3: excess kurtosis + Array shape: (dim_p, kmax) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] moments_np = np.zeros((dim_p, kmax), dtype=np.float64, order="F") + cdef double [::1,:] moments = moments_np + with nogil: + c__pdaf_diag_compute_moments(&dim_p, &dim_ens, &ens[0,0], &kmax, + &moments[0,0], &bias) + + return moments_np + + +def diag_histogram(int ncall, int dim, int dim_ens, int element, + double [::1] state, double [::1,:] ens, int [::1] hist): + r"""diag_histogram(ncall: int, dim: int, dim_ens: int, element: int, state: np.ndarray, ens: np.ndarray, hist: np.ndarray) -> Tuple[np.ndarray, float, int] + + Computing the rank histogram of an ensemble. + + A rank histogram is used to diagnose + the reliability of the ensemble [1]_. + A perfectly reliable ensemble should have + a uniform rank histogram. + + The function can be called in the + pre/poststep routine of PDAF + both before and after the analysis step + to collect the histogram information. + + References + ---------- + .. [1] Hamill, T. M. (2001). + Interpretation of rank histograms + for verifying ensemble forecasts. + Monthly Weather Review, 129(3), 550-560. + + Parameters + ---------- + ncall : int + Number of calls to routine + dim : int + State dimension + dim_ens : int + Ensemble size + element : int + Element of vector used for histogram + state : ndarray[np.float64, ndim=1] + State vector + Array shape: (dim) + ens : ndarray[np.float64, ndim=2] + State ensemble + Array shape: (dim, dim_ens) + hist : ndarray[np.intc, ndim=1] + Histogram about the state + Array shape: (dim_ens+1) + + Returns + ------- + hist : ndarray[np.intc, ndim=1] + Histogram about the state + Array shape: (dim_ens+1) + delta : double + deviation measure from flat histogram + status : int + Status flag (0=success) + """ + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] hist_np = np.asarray(hist, dtype=np.intc, order="F") + cdef double delta + cdef int status + with nogil: + c__pdaf_diag_histogram(&ncall, &dim, &dim_ens, &element, &state[0], + &ens[0,0], &hist[0], &delta, &status) + + return hist_np, delta, status + + +def diag_reliability_budget(int n_times, int dim_ens, int dim_p, + double [::1,:,:] ens_p, double [::1,:,:] obsvar, double [::1,:] obs_p): + r"""diag_reliability_budget(n_times: int, dim_ens: int, dim_p: int, ens_p: np.ndarray, obsvar: np.ndarray, obs_p: np.ndarray) -> Tuple[np.ndarray, np.ndarray] + + Compute ensemble reliability budget + + The diagnostics derives a balance relationship that decomposes the + departure between the ensemble mean and observations: + Depar^2 = Bias^2 + EnsVar + ObsUnc^2 + Residual + under the assumption of a perfectly reliable ensemble [1]_. When the + residual term is not small, one can identify the sources of + problematic ensemble representation of the uncertainty by looking at + each terms. One of the benefits of + the reliability budget diagnostics is that it can identify spatially + local issues in ensemble perturbations. + + In this subroutine, the budget array returns each term of the + reliability budget is given at each given time step. The returned + array can be used for significant t-test where each time step is used + as a sample from the population. The actual budget is the mean over + time steps except for Bias^2 term, which is given separately. This + is because the unsquared bias is used in the t-test in the original + paper. + + The subroutine does not comes with a t-test to ensure that + the reliability budget is statistically significant as done + in the original paper. However, this can be achieved with external + libraries or software if the t-test is deemed important. The t-test + should account for the temporal autocorrelation between time steps + in the given trajectory. + + The diagnostics requires a trajectory of ensemble and observations, + a trajectory of an ensemle of observation error variances. The + ensemble of observation error variances can be the square of + observation errors sampled from observation error distribution as + done in stochastic ensemble Kalman filter. In deterministic ensemble + systems, the ensemble of observation error variances can be the + observation error variances where each ensemble member has the same + value. + + References + ---------- + .. [1] Rodwell, M. J., Lang, S. T. K., Ingleby, N. B., Bormann, N., Holm, + E., Rabier, F., ... & Yamaguchi, M. (2016). Reliability in ensemble data assimilation. + Quarterly Journal of the Royal Meteorological Society, 142(694), 443-454. + + Parameters + ---------- + n_times : int + Number of time steps + dim_ens : int + Number of ensemble members + dim_p : int + Dimension of the state vector + ens_p : ndarray[np.float64, ndim=3] + Ensemble matrix over times + Array shape: (dim_p, dim_ens, n_times) + obsvar : ndarray[np.float64, ndim=3] + Squared observation error/variance at n_times + Array shape: (dim_p, dim_ens, n_times) + obs_p : ndarray[np.float64, ndim=2] + Observation vector + Array shape: (dim_p, n_times) + + Returns + ------- + budget : ndarray[np.float64, ndim=3] + Budget term for a single time step + Array shape: (dim_p, n_times, 5) + bias_2 : ndarray[np.float64, ndim=1] + bias^2 uses + Array shape: (dim_p) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=3, mode="fortran", negative_indices=False, cast=False] budget_np = np.zeros((dim_p, n_times, 5), dtype=np.float64, order="F") + cdef double [::1,:,:] budget = budget_np + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] bias_2_np = np.zeros((dim_p), dtype=np.float64, order="F") + cdef double [::1] bias_2 = bias_2_np + with nogil: + c__pdaf_diag_reliability_budget(&n_times, &dim_ens, &dim_p, + &ens_p[0,0,0], &obsvar[0,0,0], + &obs_p[0,0], &budget[0,0,0], &bias_2[0]) + + return budget_np, bias_2_np diff --git a/pyPDAF/source/src/pyPDAF/PDAF/get.pxd b/pyPDAF/source/src/pyPDAF/PDAF/get.pxd new file mode 100644 index 0000000000000000000000000000000000000000..5f55cde70fc3fa2dac19160f21ac664335b21b9d --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/get.pxd @@ -0,0 +1,19 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t +cdef extern void c__pdaf_get_assim_flag( + int* did_assim) noexcept nogil; + +cdef extern void c__pdaf_get_localfilter( + int* localfilter_out) noexcept nogil; + +cdef extern void c__pdaf_get_local_type( + int* localtype) noexcept nogil; + +cdef extern void c__pdaf_get_memberid( + int* memberid) noexcept nogil; + +cdef extern void c__pdaf_get_obsmemberid( + int* memberid) noexcept nogil; + +cdef extern void c__pdaf_get_smootherens(CFI_cdesc_t* sens_point, + int* maxlag, int* status) noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/PDAF/get.pyi b/pyPDAF/source/src/pyPDAF/PDAF/get.pyi new file mode 100644 index 0000000000000000000000000000000000000000..adb72c169b49e7ad483b02dacdc2a82fd9addbfd --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/get.pyi @@ -0,0 +1,101 @@ +# pylint: disable=unused-argument +"""Auto-generated stub file for get.pyx +""" +import typing + +import numpy as np + +def get_assim_flag() -> int: + r"""Return the flag that + indicates if the DA is performed in the last time step. + It only works for online DA systems. + + + Returns + ------- + did_assim : int + flag: (1) for assimilation; (0) else + """ + +def get_localfilter() -> int: + r"""Return whether a local filter is used. + + + Returns + ------- + lfilter : int + whether the filter is domain-localized (1) or not (0) + * 1 for local filters (including ENSRF/EAKF), + * 0 for global filters (including LEnKF, which performs covariance localization) + """ + +def get_local_type() -> int: + r"""The routine returns the information on the localization type of the selected filter. + + With this one can distinguish filters using + * domain localization (LESTKF, LETKF, LSEIK, LNETF), + * covariance localization (LEnKF), or + * covariance localization with observation handling like domain localization (ENSRF/EAKF). + + + Returns + ------- + localtype : int + * (0) no localization; global filter + * (1) domain localization (LESTKF, LETKF, LNETF, LSEIK) + * (2) covariance localization (LEnKF) + * (3) covariance loc. but observation handling like domain localization (ENSRF) + """ + +def get_memberid(memberid: int) -> int: + """Return the ensemble member id on the current process. + + For example, it can be called during the ensemble + integration if ensemble-specific forcing is read. + It can also be used in the user-supplied functions + such as :func:`py__collect_state_pdaf` and + :func:`py__distribute_state_pdaf`. + + Parameters + ---------- + memberid : int + Index in the local ensemble + + Returns + ------- + memberid : int + Index in the local ensemble + """ + +def get_obsmemberid(memberid: int) -> int: + """Return the ensemble member id + when observation operator is being applied. + + This function is used specifically for + user-supplied function :func:`py__obs_op_pdaf`. + + Parameters + ---------- + memberid : int + Index in the local ensemble + + Returns + ------- + memberid : int + Index in the local ensemble + """ + +def get_smoother_ens() -> typing.Tuple[np.ndarray, int, int]: + """Return the smoothed ensemble in earlier time steps. + + It is only used when the smoother options is used . + + Returns + ------- + sens_point_np : ndarray[np.float64, ndim=3] + Pointer to smoothed ensemble + maxlag: int + Maximum lag + status: int + Status flag + """ diff --git a/pyPDAF/source/src/pyPDAF/PDAF/get.pyx b/pyPDAF/source/src/pyPDAF/PDAF/get.pyx new file mode 100644 index 0000000000000000000000000000000000000000..fc9ed4bacd10b0ccd3e81bd3834e67bde8ff1477 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/get.pyx @@ -0,0 +1,159 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t +from pyPDAF.cfi_binding cimport CFI_type_double +from pyPDAF.cfi_binding cimport CFI_cdesc_rank3 + +def get_assim_flag(): + r"""get_assim_flag() -> int + + Return the flag that + indicates if the DA is performed in the last time step. + It only works for online DA systems. + + + Returns + ------- + did_assim : int + flag: (1) for assimilation; (0) else + """ + cdef int did_assim + with nogil: + c__pdaf_get_assim_flag(&did_assim) + + return did_assim + + +def get_localfilter(): + r"""get_localfilter() -> int + + Return whether a local filter is used. + + + Returns + ------- + lfilter : int + whether the filter is domain-localized (1) or not (0) + * 1 for local filters (including ENSRF/EAKF), + * 0 for global filters (including LEnKF, which performs covariance localization) + """ + cdef int localfilter_out + with nogil: + c__pdaf_get_localfilter(&localfilter_out) + + return localfilter_out + + +def get_local_type(): + r"""get_local_type() -> int + + The routine returns the information on the localization type of the selected filter. + + With this one can distinguish filters using + * domain localization (LESTKF, LETKF, LSEIK, LNETF), + * covariance localization (LEnKF), or + * covariance localization with observation handling like domain localization (ENSRF/EAKF). + + + Returns + ------- + localtype : int + * (0) no localization; global filter + * (1) domain localization (LESTKF, LETKF, LNETF, LSEIK) + * (2) covariance localization (LEnKF) + * (3) covariance loc. but observation handling like domain localization (ENSRF) + """ + cdef int localtype + with nogil: + c__pdaf_get_local_type(&localtype) + + return localtype + + +def get_memberid(int memberid): + """get_memberid(memberid: int) -> int + + Return the ensemble member id on the current process. + + For example, it can be called during the ensemble + integration if ensemble-specific forcing is read. + It can also be used in the user-supplied functions + such as :func:`py__collect_state_pdaf` and + :func:`py__distribute_state_pdaf`. + + Parameters + ---------- + memberid : int + Index in the local ensemble + + Returns + ------- + memberid : int + Index in the local ensemble + """ + with nogil: + c__pdaf_get_memberid(&memberid) + + return memberid + + +def get_obsmemberid(int memberid): + """get_obsmemberid(memberid: int) -> int + + Return the ensemble member id + when observation operator is being applied. + + This function is used specifically for + user-supplied function :func:`py__obs_op_pdaf`. + + Parameters + ---------- + memberid : int + Index in the local ensemble + + Returns + ------- + memberid : int + Index in the local ensemble + """ + with nogil: + c__pdaf_get_obsmemberid(&memberid) + + return memberid + + +def get_smoother_ens(): + """get_smoother_ens() -> typing.Tuple[np.ndarray, int, int] + + Return the smoothed ensemble in earlier time steps. + + It is only used when the smoother options is used . + + Returns + ------- + sens_point_np : ndarray[np.float64, ndim=3] + Pointer to smoothed ensemble + maxlag: int + Maximum lag + status: int + Status flag + """ + cdef CFI_cdesc_rank3 sens_point_cfi + cdef CFI_cdesc_t *sens_point_ptr = &sens_point_cfi + cdef int maxlag + cdef int status + with nogil: + c__pdaf_get_smootherens(sens_point_ptr, &maxlag, &status) + + cdef CFI_index_t sens_point_subscripts[3] + sens_point_subscripts[0] = 0 + sens_point_subscripts[1] = 0 + sens_point_subscripts[2] = 0 + cdef double * sens_point_ptr_np + sens_point_ptr_np = CFI_address(sens_point_ptr, sens_point_subscripts) + cdef cnp.ndarray[cnp.float64_t, ndim=3, mode="fortran", negative_indices=False, cast=False] sens_point_np = np.asarray( sens_point_ptr_np, order="F") + return sens_point_np, maxlag, status + + diff --git a/pyPDAF/source/src/pyPDAF/PDAF/iau.pxd b/pyPDAF/source/src/pyPDAF/PDAF/iau.pxd new file mode 100644 index 0000000000000000000000000000000000000000..583d296625eea31cdabee1f6bf902576a9a49634 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/iau.pxd @@ -0,0 +1,26 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t +cdef extern void c__pdaf_iau_init(int* type_iau_in, int* nsteps_iau_in, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_iau_reset(int* type_iau_in, int* nsteps_iau_in, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_iau_set_weights(int* iweights, + double* weights) noexcept nogil; + +cdef extern void c__pdaf_iau_set_pointer(CFI_cdesc_t* iau_ptr, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_iau_init_inc(int* dim_p, int* dim_ens_l, + double* ens_inc, int* flag) noexcept nogil; + +cdef extern void c__pdaf_iau_add_inc( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , + double* )) noexcept nogil; + +cdef extern void c__pdaf_iau_set_ens_pointer(CFI_cdesc_t* iau_ptr, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_iau_set_state_pointer(CFI_cdesc_t* iau_x_ptr, + int* flag) noexcept nogil; diff --git a/pyPDAF/source/src/pyPDAF/PDAF/iau.pyi b/pyPDAF/source/src/pyPDAF/PDAF/iau.pyi new file mode 100644 index 0000000000000000000000000000000000000000..cac4ed67b8ab4c420b530ac2c1dca15336760637 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/iau.pyi @@ -0,0 +1,212 @@ +# pylint: disable=unused-argument +"""Stub file for PDAF IAU module +""" +from typing import Callable, Tuple +import numpy as np + +def iau_init(type_iau_in: int, nsteps_iau_in: int) -> int: + """Initialise parameters for incremental analysis updates, IAU. + + It further allocates the array in which the ensemble increments are stored. + This array exists on all processes that are part of model tasks. + + This is usually called after :func:`pyPDAF.PDAF.init`. + It is important that this is called by all model processes because all these + processes need the information on the IAU configuration and + need to allocate the increment array. + + Parameters + ---------- + type_iau_in : int + - (0) no IAU + - (1) constant increment weight 1/nsteps_iau + - (2) Linear IAU weight with maximum in middle of IAU period. This weight + linearly increases and decreases. This type is usually used if + the IAU is applied in re-running over the previous observation period. + - (3) Zero weights for null mode (can be used to apply IAU on user side). + This stores the increment information, but does not apply the increment. + One can use :func:`pyPDAF.PDAF.iau_set_pointer` to access the increment + array. + nsteps_iau_in : int + number of time steps in IAU + + Returns + ------- + flag : int + Status flag + """ + +def iau_reset(type_iau_in: int, nsteps_iau_in: int) -> int: + """Modify the IAU type and the number of IAU time steps during a run + + While :func:`pyPDAF.PDAF.iau_init` sets the IAU type and number of IAU steps + initially, one can change these settings during a model run. + + This function has to be called by all processes that are model processes. + A common place is to call the function after an analysis step or + in `distribute_state_pdaf`. + + Parameters + ---------- + type_iau_in : int + - (0) no IAU + - (1) constant increment weight 1/nsteps_iau + - (2) Linear IAU weight with maximum in middle of IAU period. This weight + linearly increases and decreases. This type is usually used if + the IAU is applied in re-running over the previous observation period. + - (3) Zero weights for null mode (can be used to apply IAU on user side). + This stores the increment information, but does not apply the increment. + One can use :func:`pyPDAF.PDAF.iau_set_pointer` to access the increment + array. + nsteps_iau_in : int + number of time steps in IAU + + Returns + ------- + flag : int + Status flag + """ + +def iau_set_weights(iweights: int, weights: np.ndarray) -> None: + """Provide a user-specified vector of increment weights. + + While :func:`pyPDAF.PDAF.iau_init` allows to choose among + pre-defined weight functions, one might like to use a different function + and the corresponding weights can be set here. + + All model processes must call the routine. + A common place is to call the function after an analysis step or in `distribute_state_pdaf`. + + Parameters + ---------- + iweights : int + Length of weights input vector + If iweights is different from the number of IAU steps set in + :func:`pyPDAF.PDAF.iau_init` or :func:`pyPDAF.PDAF.iau_reset`, + only the minimum of iweights and the set IAU steps is filled with + the provided weights vector. + weights : ndarray[np.float64, ndim=1] + Input weight vector + Array shape: (iweights) + """ + +def iau_set_pointer() -> Tuple[np.ndarray, int]: + """Set a pointer to the ensemble increments array. + + This gives direct access to the increment array, + e.g. to analyze it or to write it into a file for restarting. + + If it is called by each single process, but it only provides a pointer to + the process-local part of the increment array. + + For domain-decomposed models, this array only includes the state vector + part for the process domain. In addition, it usually only contains a + sub-ensemble unless one uses the flexible parallelization mode with a + single model task. For the fully parallel mode, the process(es) of a + single model task only hold a single ensemble state. + + Returns + ------- + iau_ptr_np : np.ndarray + The increment array (process-local part) + flag : int + Status flag + """ + +def iau_init_inc(dim_p: int, dim_ens_l: int, ens_inc: np.ndarray) -> int: + """Fill the process-local increment array. + + A common use is when the IAU should be applied from the initial time of a run, + for example if the increment was computed in a previous assimilation run + and then stored for restarting. Since PDAF can only compute an increment + in an analysis step, the user needs to provide the increment. + + The function is called after :func:`pyPDAF.PDAF.iau_init`. + It has to be called by all processes that are model processes and one needs + to provide the task-local ensemble + (i.e. with local ensemble size `dim_ens_l=1` for the fully parallel mode, + and usually `dim_ens_l>1` for the flexible parallelization mode). + The function cannot be called in `init_ens_pdaf` since this function is only + executed by filter processes instead of all model processes. + + Parameters + ---------- + dim_p : int + PE-local dimension of model state + dim_ens_l : int + Number of ensemble members that are run by a loop for each model task + ens_inc : ndarray[np.float64, ndim=2] + PE-local increment ensemble + Array shape: (dim_p, dim_ens_l) + + Returns + ------- + flag : int + Status flag + """ + +def iau_add_inc(py__collect_state_pdaf: Callable, py__distribute_state_pdaf: Callable) -> None: + """Apply IAU to model forecasts in flexible parallel mode. + + PDAF automatically apply IAU in fully parallel model. However, one has to + apply IAU with this function in flexible parallel mode. + + This has to be used in each model time stepping. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Collect a state vector for PDAF + + py__distribute_state_pdaf : Callable + Distribute a state vector for PDAF + """ + +def iau_set_ens_pointer() -> Tuple[np.ndarray, int]: + """Set a pointer to the ensemble increments array. + + This is the same as :func:`pyPDAF.PDAF.iau_set_pointer`. + + This gives direct access to the increment array, + e.g. to analyze it or to write it into a file for restarting. + + If it is called by each single process, but it only provides a pointer to + the process-local part of the increment array. + + For domain-decomposed models, this array only includes the state vector + part for the process domain. In addition, it usually only contains a + sub-ensemble unless one uses the flexible parallelization mode with a + single model task. For the fully parallel mode, the process(es) of a + single model task only hold a single ensemble state. + + Returns + ------- + iau_ptr_np : np.ndarray + The increment array (process-local part) + flag : int + Status flag + """ + +def iau_set_state_pointer() -> Tuple[np.ndarray, int]: + """Set a pointer to the state increments array. + + This gives direct access to the increment array used in the ensemble + optimal interpolation mode. This can be used + e.g. to analyze it or to write it into a file for restarting. + + If it is called by each single process, but it only provides a pointer to + the process-local part of the increment array. + + For domain-decomposed models, this array only includes the state vector + part for the process domain. In addition, it usually only contains a + sub-ensemble unless one uses the flexible parallelization mode with a + single model task. For the fully parallel mode, the process(es) of a + single model task only hold a single ensemble state. + + Returns + ------- + iau_ptr_np : np.ndarray + The increment array (process-local part) + flag : int + Status flag + """ \ No newline at end of file diff --git a/pyPDAF/source/src/pyPDAF/PDAF/iau.pyx b/pyPDAF/source/src/pyPDAF/PDAF/iau.pyx new file mode 100644 index 0000000000000000000000000000000000000000..28713a88dc8a4f799a9ebe3b262ce523b5a4b094 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/iau.pyx @@ -0,0 +1,296 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + +def iau_init(int type_iau_in, int nsteps_iau_in): + """iau_init(type_iau_in: int, nsteps_iau_in: int) -> int + + Initialise parameters for incremental analysis updates, IAU. + + It further allocates the array in which the ensemble increments are stored. + This array exists on all processes that are part of model tasks. + + This is usually called after :func:`pyPDAF.PDAF.init`. + It is important that this is called by all model processes because all these + processes need the information on the IAU configuration and + need to allocate the increment array. + + Parameters + ---------- + type_iau_in : int + - (0) no IAU + - (1) constant increment weight 1/nsteps_iau + - (2) Linear IAU weight with maximum in middle of IAU period. This weight + linearly increases and decreases. This type is usually used if + the IAU is applied in re-running over the previous observation period. + - (3) Zero weights for null mode (can be used to apply IAU on user side). + This stores the increment information, but does not apply the increment. + One can use :func:`pyPDAF.PDAF.iau_set_pointer` to access the increment + array. + nsteps_iau_in : int + number of time steps in IAU + + Returns + ------- + flag : int + Status flag + """ + cdef int flag + with nogil: + c__pdaf_iau_init(&type_iau_in, &nsteps_iau_in, &flag) + + return flag + + +def iau_reset(int type_iau_in, int nsteps_iau_in): + """iau_reset(type_iau_in: int, nsteps_iau_in: int) -> int + + Modify the IAU type and the number of IAU time steps during a run + + While :func:`pyPDAF.PDAF.iau_init` sets the IAU type and number of IAU steps + initially, one can change these settings during a model run. + + This function has to be called by all processes that are model processes. + A common place is to call the function after an analysis step or + in `distribute_state_pdaf`. + + Parameters + ---------- + type_iau_in : int + - (0) no IAU + - (1) constant increment weight 1/nsteps_iau + - (2) Linear IAU weight with maximum in middle of IAU period. This weight + linearly increases and decreases. This type is usually used if + the IAU is applied in re-running over the previous observation period. + - (3) Zero weights for null mode (can be used to apply IAU on user side). + This stores the increment information, but does not apply the increment. + One can use :func:`pyPDAF.PDAF.iau_set_pointer` to access the increment + array. + nsteps_iau_in : int + number of time steps in IAU + + Returns + ------- + flag : int + Status flag + """ + cdef int flag + with nogil: + c__pdaf_iau_reset(&type_iau_in, &nsteps_iau_in, &flag) + + return flag + + +def iau_set_weights(int iweights, double [::1] weights): + """iau_set_weights(iweights: int, weights: np.ndarray) -> None + + Provide a user-specified vector of increment weights. + + While :func:`pyPDAF.PDAF.iau_init` allows to choose among + pre-defined weight functions, one might like to use a different function + and the corresponding weights can be set here. + + All model processes must call the routine. + A common place is to call the function after an analysis step or in `distribute_state_pdaf`. + + Parameters + ---------- + iweights : int + Length of weights input vector + If iweights is different from the number of IAU steps set in + :func:`pyPDAF.PDAF.iau_init` or :func:`pyPDAF.PDAF.iau_reset`, + only the minimum of iweights and the set IAU steps is filled with + the provided weights vector. + weights : ndarray[np.float64, ndim=1] + Input weight vector + Array shape: (iweights) + """ + with nogil: + c__pdaf_iau_set_weights(&iweights, &weights[0]) + + + +def iau_set_pointer(): + """iau_set_pointer() -> Tuple[np.ndarray, int] + + Set a pointer to the ensemble increments array. + + This gives direct access to the increment array, + e.g. to analyze it or to write it into a file for restarting. + + If it is called by each single process, but it only provides a pointer to + the process-local part of the increment array. + + For domain-decomposed models, this array only includes the state vector + part for the process domain. In addition, it usually only contains a + sub-ensemble unless one uses the flexible parallelization mode with a + single model task. For the fully parallel mode, the process(es) of a + single model task only hold a single ensemble state. + + Returns + ------- + iau_ptr_np : np.ndarray + The increment array (process-local part) + flag : int + Status flag + """ + cdef CFI_cdesc_rank2 iau_ptr_cfi + cdef CFI_cdesc_t *iau_ptr_ptr = &iau_ptr_cfi + cdef int flag + with nogil: + c__pdaf_iau_set_pointer(iau_ptr_ptr, &flag) + + cdef CFI_index_t iau_ptr_subscripts[2] + iau_ptr_subscripts[0] = 0 + iau_ptr_subscripts[1] = 0 + cdef double * iau_ptr_ptr_np + iau_ptr_ptr_np = CFI_address(iau_ptr_ptr, iau_ptr_subscripts) + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] iau_ptr_np = np.asarray( iau_ptr_ptr_np, order="F") + return iau_ptr_np, flag + + +def iau_init_inc(int dim_p, int dim_ens_l, double [::1,:] ens_inc): + """iau_init_inc(dim_p: int, dim_ens_l: int, ens_inc: np.ndarray) -> int + + Fill the process-local increment array. + + A common use is when the IAU should be applied from the initial time of a run, + for example if the increment was computed in a previous assimilation run + and then stored for restarting. Since PDAF can only compute an increment + in an analysis step, the user needs to provide the increment. + + The function is called after :func:`pyPDAF.PDAF.iau_init`. + It has to be called by all processes that are model processes and one needs + to provide the task-local ensemble + (i.e. with local ensemble size `dim_ens_l=1` for the fully parallel mode, + and usually `dim_ens_l>1` for the flexible parallelization mode). + The function cannot be called in `init_ens_pdaf` since this function is only + executed by filter processes instead of all model processes. + + Parameters + ---------- + dim_p : int + PE-local dimension of model state + dim_ens_l : int + Number of ensemble members that are run by a loop for each model task + ens_inc : ndarray[np.float64, ndim=2] + PE-local increment ensemble + Array shape: (dim_p, dim_ens_l) + + Returns + ------- + flag : int + Status flag + """ + cdef int flag + with nogil: + c__pdaf_iau_init_inc(&dim_p, &dim_ens_l, &ens_inc[0,0], &flag) + + return flag + + +def iau_add_inc(py__collect_state_pdaf, py__distribute_state_pdaf): + """iau_add_inc(py__collect_state_pdaf: Callable, py__distribute_state_pdaf: Callable) -> None + + Apply IAU to model forecasts in flexible parallel mode. + + PDAF automatically apply IAU in fully parallel model. However, one has to + apply IAU with this function in flexible parallel mode. + + This has to be used in each model time stepping. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Collect a state vector for PDAF + + py__distribute_state_pdaf : Callable + Distribute a state vector for PDAF + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + with nogil: + c__pdaf_iau_add_inc(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf) + +def iau_set_ens_pointer(): + """iau_set_ens_pointer() -> Tuple[np.ndarray, int] + + Set a pointer to the ensemble increments array. + + This is the same as :func:`pyPDAF.PDAF.iau_set_pointer`. + + This gives direct access to the increment array, + e.g. to analyze it or to write it into a file for restarting. + + If it is called by each single process, but it only provides a pointer to + the process-local part of the increment array. + + For domain-decomposed models, this array only includes the state vector + part for the process domain. In addition, it usually only contains a + sub-ensemble unless one uses the flexible parallelization mode with a + single model task. For the fully parallel mode, the process(es) of a + single model task only hold a single ensemble state. + + Returns + ------- + iau_ptr_np : np.ndarray + The increment array (process-local part) + flag : int + Status flag + """ + cdef CFI_cdesc_rank2 iau_ptr_cfi + cdef CFI_cdesc_t *iau_ptr_ptr = &iau_ptr_cfi + cdef int flag + with nogil: + c__pdaf_iau_set_ens_pointer(iau_ptr_ptr, &flag) + + cdef CFI_index_t iau_ptr_subscripts[2] + iau_ptr_subscripts[0] = 0 + iau_ptr_subscripts[1] = 0 + cdef double * iau_ptr_ptr_np + iau_ptr_ptr_np = CFI_address(iau_ptr_ptr, iau_ptr_subscripts) + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] iau_ptr_np = np.asarray( iau_ptr_ptr_np, order="F") + return iau_ptr_np, flag + +def iau_set_state_pointer(): + """iau_set_state_pointer() -> Tuple[np.ndarray, int] + + Set a pointer to the state increments array. + + This gives direct access to the increment array used in the ensemble + optimal interpolation mode. This can be used + e.g. to analyze it or to write it into a file for restarting. + + If it is called by each single process, but it only provides a pointer to + the process-local part of the increment array. + + For domain-decomposed models, this array only includes the state vector + part for the process domain. In addition, it usually only contains a + sub-ensemble unless one uses the flexible parallelization mode with a + single model task. For the fully parallel mode, the process(es) of a + single model task only hold a single ensemble state. + + Returns + ------- + iau_ptr_np : np.ndarray + The increment array (process-local part) + flag : int + Status flag + """ + cdef CFI_cdesc_rank1 iau_x_ptr_cfi + cdef CFI_cdesc_t *iau_x_ptr_ptr = &iau_x_ptr_cfi + cdef int flag + with nogil: + c__pdaf_iau_set_state_pointer(iau_x_ptr_ptr, &flag) + + cdef CFI_index_t iau_x_ptr_subscripts[1] + iau_x_ptr_subscripts[0] = 0 + cdef double * iau_x_ptr_ptr_np + iau_x_ptr_ptr_np = CFI_address(iau_x_ptr_ptr, iau_x_ptr_subscripts) + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] iau_x_ptr_np = np.asarray( iau_x_ptr_ptr_np, order="F") + return iau_x_ptr_np, flag \ No newline at end of file diff --git a/pyPDAF/source/src/pyPDAF/PDAF/iau_internal.pxd b/pyPDAF/source/src/pyPDAF/PDAF/iau_internal.pxd new file mode 100644 index 0000000000000000000000000000000000000000..15ad877b233bc6d3aab455c3b727244a031491e9 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/iau_internal.pxd @@ -0,0 +1,19 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t +cdef extern void c__pdaf_iau_init_weights(int* type_iau, + int* nsteps_iau) noexcept nogil; + +cdef extern void c__pdaf_iau_update_inc( + CFI_cdesc_t* ens_ana, CFI_cdesc_t* state_ana) noexcept nogil; + +cdef extern void c__pdaf_iau_add_inc_ens(int* step, int* dim_p, + int* dim_ens_task, CFI_cdesc_t* ens, CFI_cdesc_t* state, + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , + double* )) noexcept nogil; + + +cdef extern void c__pdaf_iau_update_ens( + CFI_cdesc_t* ens, CFI_cdesc_t* state) noexcept nogil; + +cdef extern void c__pdaf_iau_dealloc() noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/PDAF/iau_internal.pyx b/pyPDAF/source/src/pyPDAF/PDAF/iau_internal.pyx new file mode 100644 index 0000000000000000000000000000000000000000..18a9f83a840342d5b76a8dc3d0366fbcda1a1ed5 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/iau_internal.pyx @@ -0,0 +1,253 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + +try: + import mpi4py + mpi4py.rc.initialize = False +except ImportError: + pass + +# Global error handler +def global_except_hook(exctype, value, traceback): + from traceback import print_exception + try: + import mpi4py.MPI + + if mpi4py.MPI.Is_initialized(): + try: + sys.stderr.write('Uncaught exception was ''detected on rank {}.\n'.format( + mpi4py.MPI.COMM_WORLD.Get_rank())) + print_exception(exctype, value, traceback) + sys.stderr.write("\n") + sys.stderr.flush() + finally: + try: + mpi4py.MPI.COMM_WORLD.Abort(1) + except Exception as e: + sys.stderr.write('MPI Abort failed, this process will hang.\n') + sys.stderr.flush() + raise e + else: + sys.__excepthook__(exctype, value, traceback) + except ImportError: + sys.__excepthook__(exctype, value, traceback) + +sys.excepthook = global_except_hook + +def iau_init_weights(int type_iau, int nsteps_iau): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + type_iau : int + Type of IAU, (0) no IAU + nsteps_iau : int + number of time steps in IAU + + Returns + ------- + """ + with nogil: + c__pdaf_iau_init_weights(&type_iau, &nsteps_iau) + + + +def iau_update_inc(double [::1,:] ens_ana, double [::1] state_ana): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + ens_ana : ndarray[np.float64, ndim=2] + PE-local analysis ensemble + Array shape: (:, :) + state_ana : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (:) + + Returns + ------- + ens_ana : ndarray[np.float64, ndim=2] + PE-local analysis ensemble + Array shape: (:, :) + """ + cdef CFI_cdesc_rank2 ens_ana_cfi + cdef CFI_cdesc_t *ens_ana_ptr = &ens_ana_cfi + cdef size_t ens_ana_nbytes = ens_ana.nbytes + cdef CFI_index_t ens_ana_extent[2] + ens_ana_extent[0] = ens_ana.shape[0] + ens_ana_extent[1] = ens_ana.shape[1] + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_ana_np = np.asarray(ens_ana, dtype=np.float64, order="F") + + cdef CFI_cdesc_rank1 state_ana_cfi + cdef CFI_cdesc_t *state_ana_ptr = &state_ana_cfi + cdef size_t state_ana_nbytes = state_ana.nbytes + cdef CFI_index_t state_ana_extent[1] + state_ana_extent[0] = state_ana.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_ana_np = np.asarray(state_ana, dtype=np.float64, order="F") + + + with nogil: + CFI_establish(ens_ana_ptr, &ens_ana[0,0], CFI_attribute_other, + CFI_type_double , ens_ana_nbytes, 2, ens_ana_extent) + + CFI_establish(state_ana_ptr, &state_ana[0], CFI_attribute_other, + CFI_type_double , state_ana_nbytes, 1, state_ana_extent) + + c__pdaf_iau_update_inc(ens_ana_ptr, state_ana_ptr) + + return ens_ana_np, state_ana_np + + +def iau_add_inc_ens(int step, int dim_p, int dim_ens_task, + double [::1,:] ens, double [::1] state, py__collect_state_pdaf, py__distribute_state_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Time step + dim_p : int + PE-local dimension of model state + dim_ens_task : int + Ensemble size of model task + ens : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (:, :) + state : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (:) + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + + Returns + ------- + ens : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (:, :) + """ + cdef CFI_cdesc_rank2 ens_cfi + cdef CFI_cdesc_t *ens_ptr = &ens_cfi + cdef size_t ens_nbytes = ens.nbytes + cdef CFI_index_t ens_extent[2] + ens_extent[0] = ens.shape[0] + ens_extent[1] = ens.shape[1] + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_np = np.asarray(ens, dtype=np.float64, order="F") + + cdef CFI_cdesc_rank1 state_cfi + cdef CFI_cdesc_t *state_ptr = &state_cfi + cdef size_t state_nbytes = state.nbytes + cdef CFI_index_t state_extent[1] + state_extent[0] = state.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_np = np.asarray(state, dtype=np.float64, order="F") + + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + with nogil: + CFI_establish(ens_ptr, &ens[0,0], CFI_attribute_other, + CFI_type_double , ens_nbytes, 2, ens_extent) + + CFI_establish(state_ptr, &state[0], CFI_attribute_other, + CFI_type_double , state_nbytes, 1, state_extent) + + c__pdaf_iau_add_inc_ens(&step, &dim_p, &dim_ens_task, ens_ptr, state_ptr, + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf) + + return ens_np, state_np + + +def iau_update_ens(double [::1,:] ens, double [::1] state): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + ens : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (:, :) + state : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (:) + + Returns + ------- + ens : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (:, :) + """ + cdef CFI_cdesc_rank2 ens_cfi + cdef CFI_cdesc_t *ens_ptr = &ens_cfi + cdef size_t ens_nbytes = ens.nbytes + cdef CFI_index_t ens_extent[2] + ens_extent[0] = ens.shape[0] + ens_extent[1] = ens.shape[1] + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_np = np.asarray(ens, dtype=np.float64, order="F") + + cdef CFI_cdesc_rank1 state_cfi + cdef CFI_cdesc_t *state_ptr = &state_cfi + cdef size_t state_nbytes = state.nbytes + cdef CFI_index_t state_extent[1] + state_extent[0] = state.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_np = np.asarray(state, dtype=np.float64, order="F") + + with nogil: + CFI_establish(ens_ptr, &ens[0,0], CFI_attribute_other, + CFI_type_double , ens_nbytes, 2, ens_extent) + + CFI_establish(state_ptr, &state[0], CFI_attribute_other, + CFI_type_double , state_nbytes, 1, state_extent) + + c__pdaf_iau_update_ens(ens_ptr, state_ptr) + + return ens_np, state_np + + +def iau_dealloc(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdaf_iau_dealloc() + + + diff --git a/pyPDAF/source/src/pyPDAF/PDAF/internal.pxd b/pyPDAF/source/src/pyPDAF/PDAF/internal.pxd new file mode 100644 index 0000000000000000000000000000000000000000..a56a15e3daf990af7b854c9bf34244a196a2673d --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/internal.pxd @@ -0,0 +1,1465 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t + +cdef extern void c__pdaf_mpi_init() noexcept nogil; + +cdef extern void c__pdaf_timeit(int* timerid, char* operation) noexcept nogil; + + +cdef extern void c__pdaf_set_forget(int* step, int* localfilter, + int* dim_obs_p, int* dim_ens, double* mens_p, double* mstate_p, + double* obs_p, + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + double* forget_in, double* forget_out, + int* screen) noexcept nogil; + +cdef extern void c__pdaf_set_iparam_filters(int* id, int* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_set_rparam_filters(int* id, double* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_set_forget_local(int* domain, int* step, + int* dim_obs_l, int* dim_ens, double* hx_l, double* hxbar_l, + double* obs_l, + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + double* forget, double* aforget) noexcept nogil; + +cdef extern void c__pdaf_fcst_operations(int* step, + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_letkf_ana_t(int* domain_p, int* step, int* dim_l, + int* dim_obs_l, int* dim_ens, double* state_l, double* ainv_l, + double* ens_l, double* hz_l, double* hxbar_l, double* obs_l, + double* rndmat, double* forget, + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + int* type_trans, int* screen, int* debug, + int* flag) noexcept nogil; + +cdef extern void c__pdafseik_update(int* step, int* dim_p, int* dim_obs_p, + int* dim_ens, int* rank, double* state_p, double* uinv, double* ens_p, + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* screen, int* subtype, int* flag) noexcept nogil; + +cdef extern void c__pdaf3dvar_update(int* step, int* dim_p, int* dim_obs_p, + int* dim_ens, int* dim_cvec, double* state_p, double* ainv, + double* ens_p, + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + int* screen, int* flag) noexcept nogil; + +cdef extern void c__pdafen3dvar_update_estkf(int* step, int* dim_p, + int* dim_obs_p, int* dim_ens, int* dim_cvec_ens, double* state_p, + double* ainv, double* ens_p, + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + int* screen, int* flag) noexcept nogil; + +cdef extern void c__pdafen3dvar_update_lestkf(int* step, int* dim_p, + int* dim_obs_p, int* dim_ens, int* dim_cvec_ens, double* state_p, + double* ainv, double* ens_p, + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_f_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + int* screen, int* flag) noexcept nogil; + +cdef extern void c__pdafetkf_update(int* step, int* dim_p, int* dim_obs_p, + int* dim_ens, double* state_p, double* ainv, double* ens_p, + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* screen, int* subtype, int* dim_lag, double* sens_p, + int* cnt_maxlag, int* flag) noexcept nogil; + +cdef extern void c__pdaf_netf_ana(int* step, int* dim_p, int* dim_obs_p, + int* dim_ens, double* state_p, double* ens_p, double* rndmat, + double* t, int* type_forget, double* forget, int* type_winf, + double* limit_winf, int* type_noise, double* noise_amp, double* hz_p, + double* obs_p, + void (*c__likelihood_pdaf)(int* , int* , double* , double* , double* ), + int* screen, int* debug, int* flag) noexcept nogil; + +cdef extern void c__pdaf_netf_smoothert(int* step, int* dim_p, + int* dim_obs_p, int* dim_ens, double* ens_p, double* rndmat, double* ta, + double* hx_p, double* obs_p, + void (*c__likelihood_pdaf)(int* , int* , double* , double* , double* ), + int* screen, int* flag) noexcept nogil; + +cdef extern void c__pdaf_smoother_netf(int* dim_p, int* dim_ens, + int* dim_lag, double* ainv, double* sens_p, int* cnt_maxlag, + int* screen) noexcept nogil; + +cdef extern void c__pdaf_lnetf_ana(int* domain_p, int* step, int* dim_l, + int* dim_obs_l, int* dim_ens, double* ens_l, double* hx_l, + double* obs_l, double* rndmat, + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + int* type_forget, double* forget, int* type_winf, double* limit_winf, + int* cnt_small_svals, double* eff_dimens, double* t, int* screen, + int* debug, int* flag) noexcept nogil; + +cdef extern void c__pdaf_lnetf_smoothert(int* domain_p, int* step, + int* dim_obs_f, int* dim_obs_l, int* dim_ens, double* hx_f, + double* rndmat, + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + int* screen, double* t, int* flag) noexcept nogil; + +cdef extern void c__pdaf_smoother_lnetf(int* domain_p, int* step, + int* dim_p, int* dim_l, int* dim_ens, int* dim_lag, double* ainv, + double* ens_l, double* sens_p, int* cnt_maxlag, + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + int* screen) noexcept nogil; + +cdef extern void c__pdaf_memcount_ini( + int* ncounters) noexcept nogil; + +cdef extern void c__pdaf_memcount_define(char* stortype, + int* wordlength) noexcept nogil; + +cdef extern void c__pdaf_memcount(int* id, char* stortype, + int* dim) noexcept nogil; + +cdef extern void c__pdaf_init_filters(int* type_filter, int* subtype, + int* param_int, int* dim_pint, double* param_real, int* dim_preal, + char* filterstr, bint* ensemblefilter, bint* fixedbasis, int* screen, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_alloc_filters(char* filterstr, int* subtype, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_configinfo_filters(int* subtype, + int* verbose) noexcept nogil; + +cdef extern void c__pdaf_options_filters( + int* type_filter) noexcept nogil; + +cdef extern void c__pdaf_print_info_filters( + int* printtype) noexcept nogil; + +cdef extern void c__pdaf_allreduce(int* val_p, int* val_g, int* mpitype, + int* mpiop, int* status) noexcept nogil; + +cdef extern void c__pdaflseik_update(int* step, int* dim_p, int* dim_obs_f, + int* dim_ens, int* rank, double* state_p, double* uinv, double* ens_p, + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* screen, int* subtype, int* flag) noexcept nogil; + +cdef extern void c__pdaf_ensrf_init(int* subtype, int* param_int, + int* dim_pint, double* param_real, int* dim_preal, + bint* ensemblefilter, bint* fixedbasis, int* verbose, + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_ensrf_alloc( + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_ensrf_config(int* subtype, + int* verbose) noexcept nogil; + +cdef extern void c__pdaf_ensrf_set_iparam(int* id, int* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_ensrf_set_rparam(int* id, double* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_ensrf_options() noexcept nogil; + +cdef extern void c__pdaf_ensrf_memtime( + int* printtype) noexcept nogil; + +cdef extern void c__pdaf_estkf_ana_fixed(int* step, int* dim_p, + int* dim_obs_p, int* dim_ens, int* rank, double* state_p, double* ainv, + double* ens_p, double* hl_p, double* hxbar_p, double* obs_p, + double* forget, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + int* screen, int* type_sqrt, int* debug, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_etkf_ana_fixed(int* step, int* dim_p, + int* dim_obs_p, int* dim_ens, double* state_p, double* ainv, + double* ens_p, double* hz_p, double* hxbar_p, double* obs_p, + double* forget, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + int* screen, int* debug, int* flag) noexcept nogil; + +cdef extern void c__pdafestkf_update(int* step, int* dim_p, int* dim_obs_p, + int* dim_ens, double* state_p, double* ainv, double* ens_p, + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* screen, int* subtype, int* envar_mode, int* dim_lag, + double* sens_p, int* cnt_maxlag, int* flag) noexcept nogil; + +cdef extern void c__pdaflknetf_update_step(int* step, int* dim_p, + int* dim_obs_f, int* dim_ens, double* state_p, double* ainv, + double* ens_p, + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prodrinva_hyb_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__likelihood_hyb_l_pdaf)(int* , int* , int* , double* , + double* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* screen, int* subtype, int* flag) noexcept nogil; + +cdef extern void c__pdafletkf_update(int* step, int* dim_p, int* dim_obs_f, + int* dim_ens, double* state_p, double* ainv, double* ens_p, + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* screen, int* subtype, int* dim_lag, double* sens_p, + int* cnt_maxlag, int* flag) noexcept nogil; + +cdef extern void c__pdaf_lseik_ana_trans(int* domain_p, int* step, + int* dim_l, int* dim_obs_l, int* dim_ens, int* rank, double* state_l, + double* uinv_l, double* ens_l, double* hl_l, double* hxbar_l, + double* obs_l, double* omegat_in, double* forget, + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + int* nm1vsn, int* type_sqrt, int* screen, int* debug, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_en3dvar_optim_lbfgs(int* step, int* dim_p, + int* dim_ens, int* dim_cvec_p, int* dim_obs_p, double* ens_p, + double* obs_p, double* dy_p, double* v_p, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + int* opt_parallel, int* screen) noexcept nogil; + +cdef extern void c__pdaf_en3dvar_optim_cgplus(int* step, int* dim_p, + int* dim_ens, int* dim_cvec_p, int* dim_obs_p, double* ens_p, + double* obs_p, double* dy_p, double* v_p, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + int* opt_parallel, int* screen) noexcept nogil; + +cdef extern void c__pdaf_en3dvar_optim_cg(int* step, int* dim_p, + int* dim_ens, int* dim_cvec_p, int* dim_obs_p, double* ens_p, + double* obs_p, double* dy_p, double* v_p, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + int* opt_parallel, int* screen) noexcept nogil; + +cdef extern void c__pdaf_en3dvar_costf_cvt(int* step, int* iter, + int* dim_p, int* dim_ens, int* dim_cvec_p, int* dim_obs_p, + double* ens_p, double* obs_p, double* dy_p, double* v_p, double* j_tot, + double* gradj, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + int* opt_parallel) noexcept nogil; + +cdef extern void c__pdaf_en3dvar_costf_cg_cvt(int* step, int* iter, + int* dim_p, int* dim_ens, int* dim_cvec_p, int* dim_obs_p, + double* ens_p, double* obs_p, double* dy_p, double* v_p, double* d_p, + double* j_tot, double* gradj, double* hessjd, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + int* opt_parallel) noexcept nogil; + +cdef extern void c__pdaf_gather_ens(int* dim_p, int* dim_ens_p, + CFI_cdesc_t* ens, CFI_cdesc_t* state, int* screen) noexcept nogil; + +cdef extern void c__pdaf_scatter_ens(int* dim_p, int* dim_ens_p, + CFI_cdesc_t* ens, CFI_cdesc_t* state, + int* screen) noexcept nogil; + +cdef extern void c__pdaf_hyb3dvar_optim_lbfgs(int* step, int* dim_p, + int* dim_ens, int* dim_cv_par_p, int* dim_cv_ens_p, int* dim_obs_p, + double* ens_p, double* obs_p, double* dy_p, double* v_par_p, + double* v_ens_p, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + int* opt_parallel, double* beta_3dvar, + int* screen) noexcept nogil; + +cdef extern void c__pdaf_hyb3dvar_optim_cgplus(int* step, int* dim_p, + int* dim_ens, int* dim_cv_par_p, int* dim_cv_ens_p, int* dim_obs_p, + double* ens_p, double* obs_p, double* dy_p, double* v_par_p, + double* v_ens_p, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + int* opt_parallel, double* beta_3dvar, + int* screen) noexcept nogil; + +cdef extern void c__pdaf_hyb3dvar_optim_cg(int* step, int* dim_p, + int* dim_ens, int* dim_cv_par_p, int* dim_cv_ens_p, int* dim_obs_p, + double* ens_p, double* obs_p, double* dy_p, double* v_par_p, + double* v_ens_p, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + int* opt_parallel, double* beta_3dvar, + int* screen) noexcept nogil; + +cdef extern void c__pdaf_hyb3dvar_costf_cvt(int* step, int* iter, + int* dim_p, int* dim_ens, int* dim_cv_p, int* dim_cv_par_p, + int* dim_cv_ens_p, int* dim_obs_p, double* ens_p, double* obs_p, + double* dy_p, double* v_par_p, double* v_ens_p, double* v_p, + double* j_tot, double* gradj, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + int* opt_parallel, double* beta) noexcept nogil; + +cdef extern void c__pdaf_hyb3dvar_costf_cg_cvt(int* step, int* iter, + int* dim_p, int* dim_ens, int* dim_cv_par_p, int* dim_cv_ens_p, + int* dim_obs_p, double* ens_p, double* obs_p, double* dy_p, + double* v_par_p, double* v_ens_p, double* d_par_p, double* d_ens_p, + double* j_tot, double* gradj_par, double* gradj_ens, + double* hessjd_par, double* hessjd_ens, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + int* opt_parallel, double* beta) noexcept nogil; + +cdef extern void c__pdaf_print_version() noexcept nogil; + +cdef extern void c__pdafen3dvar_analysis_cvt(int* step, int* dim_p, + int* dim_obs_p, int* dim_ens, int* dim_cvec_ens, double* state_p, + double* ens_p, double* state_inc_p, double* hxbar_p, double* obs_p, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + int* screen, int* type_opt, int* debug, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_sisort(int* n, + double* veca) noexcept nogil; + +cdef extern void c__pdaf_enkf_ana_rlm(int* step, int* dim_p, + int* dim_obs_p, int* dim_obs, int* dim_ens, int* rank_ana, double* state_p, + double* ens_p, double* hzb, double* hx_p, double* hxbar_p, + double* obs_p, + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + int* screen, int* debug, int* flag) noexcept nogil; + +cdef extern void c__pdaf_smoother_enkf(int* dim_p, int* dim_ens, + int* dim_lag, double* ainv, double* sens_p, int* cnt_maxlag, + double* forget, int* screen) noexcept nogil; + +cdef extern void c__pdafensrf_update(int* step, int* dim_p, int* dim_obs_p, + int* dim_ens, double* state_p, double* ens_p, + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__localize_covar_serial_pdaf)(int* , int* , int* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* screen, int* subtype, int* flag) noexcept nogil; + +cdef extern void c__pdaf_pf_ana(int* step, int* dim_p, int* dim_obs_p, + int* dim_ens, double* state_p, double* ens_p, int* type_resample, + int* type_winf, double* limit_winf, int* type_noise, double* noise_amp, + double* hz_p, double* obs_p, + void (*c__likelihood_pdaf)(int* , int* , double* , double* , double* ), + int* screen, int* debug, int* flag) noexcept nogil; + +cdef extern void c__pdaf_pf_resampling(int* method, int* nin, int* nout, + double* weights, int* ids, int* screen) noexcept nogil; + +cdef extern void c__pdaf_mvnormalize(int* mode, int* dim_state, + int* dim_field, int* offset, int* ncol, double* states, double* stddev, + int* status) noexcept nogil; + +cdef extern void c__pdaf_3dvar_init(int* subtype, int* param_int, + int* dim_pint, double* param_real, int* dim_preal, + bint* ensemblefilter, bint* fixedbasis, int* verbose, + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_3dvar_alloc(int* subtype, + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_3dvar_config(int* subtype, + int* verbose) noexcept nogil; + +cdef extern void c__pdaf_3dvar_set_iparam(int* id, int* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_3dvar_set_rparam(int* id, double* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_3dvar_options() noexcept nogil; + +cdef extern void c__pdaf_3dvar_memtime( + int* printtype) noexcept nogil; + +cdef extern void c__pdaf_reset_dim_ens(int* dim_ens_in, + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_reset_dim_p(int* dim_p_in, + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_3dvar_optim_lbfgs(int* step, int* dim_p, + int* dim_cvec_p, int* dim_obs_p, double* obs_p, double* dy_p, + double* v_p, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + int* opt_parallel, int* screen) noexcept nogil; + +cdef extern void c__pdaf_3dvar_optim_cgplus(int* step, int* dim_p, + int* dim_cvec_p, int* dim_obs_p, double* obs_p, double* dy_p, + double* v_p, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + int* opt_parallel, int* screen) noexcept nogil; + +cdef extern void c__pdaf_3dvar_optim_cg(int* step, int* dim_p, + int* dim_cvec_p, int* dim_obs_p, double* obs_p, double* dy_p, + double* v_p, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + int* opt_parallel, int* screen) noexcept nogil; + +cdef extern void c__pdaf_3dvar_costf_cvt(int* step, int* iter, int* dim_p, + int* dim_cvec_p, int* dim_obs_p, double* obs_p, double* dy_p, + double* v_p, double* j_tot, double* gradj, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + int* opt_parallel) noexcept nogil; + +cdef extern void c__pdaf_3dvar_costf_cg_cvt(int* step, int* iter, + int* dim_p, int* dim_cvec_p, int* dim_obs_p, double* obs_p, + double* dy_p, double* v_p, double* d_p, double* j_tot, double* gradj, + double* hessjd, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + int* opt_parallel) noexcept nogil; + +cdef extern void c__pdaf_lknetf_analysis_t(int* domain_p, int* step, + int* dim_l, int* dim_obs_l, int* dim_ens, double* state_l, + double* ainv_l, double* ens_l, double* hx_l, double* hxbar_l, + double* obs_l, double* rndmat, double* forget, + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + int* screen, int* type_forget, double* eff_dimens, int* type_hyb, + double* hyb_g, double* hyb_k, double* gamma, double* skew_mabs, + double* kurt_mabs, int* flag) noexcept nogil; + +cdef extern void c__pdaf_get_ensstats(CFI_cdesc_t* skew_ptr, + CFI_cdesc_t* kurt_ptr, int* status) noexcept nogil; + +cdef extern void c__pdaf_estkf_init(int* subtype, int* param_int, + int* dim_pint, double* param_real, int* dim_preal, + bint* ensemblefilter, bint* fixedbasis, int* verbose, + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_estkf_alloc( + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_estkf_config(int* subtype, + int* verbose) noexcept nogil; + +cdef extern void c__pdaf_estkf_set_iparam(int* id, int* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_estkf_set_rparam(int* id, double* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_estkf_options() noexcept nogil; + +cdef extern void c__pdaf_estkf_memtime( + int* printtype) noexcept nogil; + +cdef extern void c__pdaf_gen_obs(int* step, int* dim_p, int* dim_obs_f, + int* dim_ens, double* state_p, double* ainv, double* ens_p, + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__get_obs_f_pdaf)(int* , int* , double* ), + void (*c__init_obserr_f_pdaf)(int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* screen, int* flag) noexcept nogil; + +cdef extern void c__pdafobs_init(int* step, int* dim_p, int* dim_ens, + int* dim_obs_p, double* state_p, double* ens_p, + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + int* screen, int* debug, bint* do_ens_mean, bint* do_init_dim, + bint* do_hx, bint* do_hxbar, + bint* do_init_obs) noexcept nogil; + +cdef extern void c__pdafobs_init_local(int* domain_p, int* step, + int* dim_obs_l, int* dim_obs_f, int* dim_ens, + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + int* debug) noexcept nogil; + +cdef extern void c__pdafobs_init_obsvars(int* step, int* dim_obs_p, + void (*c__init_obsvars_pdaf)(int* , int* , + double* )) noexcept nogil; + + +cdef extern void c__pdafobs_dealloc() noexcept nogil; + +cdef extern void c__pdafobs_dealloc_local() noexcept nogil; + +cdef extern void c__pdaf_netf_init(int* subtype, int* param_int, + int* dim_pint, double* param_real, int* dim_preal, + bint* ensemblefilter, bint* fixedbasis, int* verbose, + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_netf_alloc( + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_netf_config(int* subtype, + int* verbose) noexcept nogil; + +cdef extern void c__pdaf_netf_set_iparam(int* id, int* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_netf_set_rparam(int* id, double* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_netf_options() noexcept nogil; + +cdef extern void c__pdaf_netf_memtime( + int* printtype) noexcept nogil; + +cdef extern void c__pdaf_lenkf_init(int* subtype, int* param_int, + int* dim_pint, double* param_real, int* dim_preal, + bint* ensemblefilter, bint* fixedbasis, int* verbose, + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_lenkf_alloc( + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_lenkf_config(int* subtype, + int* verbose) noexcept nogil; + +cdef extern void c__pdaf_lenkf_set_iparam(int* id, int* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_lenkf_set_rparam(int* id, double* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_lenkf_options() noexcept nogil; + +cdef extern void c__pdaf_lenkf_memtime( + int* printtype) noexcept nogil; + +cdef extern void c__pdaf_lseik_init(int* subtype, int* param_int, + int* dim_pint, double* param_real, int* dim_preal, + bint* ensemblefilter, bint* fixedbasis, int* verbose, + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_lseik_alloc( + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_lseik_config(int* subtype, + int* verbose) noexcept nogil; + +cdef extern void c__pdaf_lseik_set_iparam(int* id, int* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_lseik_set_rparam(int* id, double* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_lseik_options() noexcept nogil; + +cdef extern void c__pdaf_lseik_memtime( + int* printtype) noexcept nogil; + +cdef extern void c__pdaf_etkf_init(int* subtype, int* param_int, + int* dim_pint, double* param_real, int* dim_preal, + bint* ensemblefilter, bint* fixedbasis, int* verbose, + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_etkf_alloc( + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_etkf_config(int* subtype, + int* verbose) noexcept nogil; + +cdef extern void c__pdaf_etkf_set_iparam(int* id, int* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_etkf_set_rparam(int* id, double* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_etkf_options() noexcept nogil; + +cdef extern void c__pdaf_etkf_memtime( + int* printtype) noexcept nogil; + +cdef extern void c__pdaflenkf_update(int* step, int* dim_p, int* dim_obs_p, + int* dim_ens, double* state_p, double* ens_p, + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__localize_covar_pdaf)(int* , int* , double* , double* ), + int* screen, int* subtype, int* flag) noexcept nogil; + +cdef extern void c__pdaf_pf_init(int* subtype, int* param_int, + int* dim_pint, double* param_real, int* dim_preal, + bint* ensemblefilter, bint* fixedbasis, int* verbose, + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_pf_alloc(int* outflag) noexcept nogil; + +cdef extern void c__pdaf_pf_config(int* subtype, + int* verbose) noexcept nogil; + +cdef extern void c__pdaf_pf_set_iparam(int* id, int* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_pf_set_rparam(int* id, double* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_pf_options() noexcept nogil; + +cdef extern void c__pdaf_pf_memtime( + int* printtype) noexcept nogil; + +cdef extern void c__pdaf_lknetf_ana_letkft(int* domain_p, int* step, + int* dim_l, int* dim_obs_l, int* dim_ens, double* state_l, + double* ainv_l, double* ens_l, double* hz_l, double* hxbar_l, + double* obs_l, double* rndmat, double* forget, + void (*c__prodrinva_hyb_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + double* gamma, int* screen, int* type_forget, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_lknetf_ana_lnetf(int* domain_p, int* step, + int* dim_l, int* dim_obs_l, int* dim_ens, double* ens_l, double* hx_l, + double* rndmat, double* obs_l, + void (*c__likelihood_hyb_l_pdaf)(int* , int* , int* , double* , + double* , double* , double* ), + int* cnt_small_svals, double* n_eff_all, double* gamma, int* screen, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_enkf_ana_rsm(int* step, int* dim_p, + int* dim_obs_p, int* dim_obs, int* dim_ens, int* rank_ana, double* state_p, + double* ens_p, double* hx_p, double* hxbar_p, double* obs_p, + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + int* screen, int* debug, int* flag) noexcept nogil; + +cdef extern void c__pdaf_lknetf_init(int* subtype, int* param_int, + int* dim_pint, double* param_real, int* dim_preal, + bint* ensemblefilter, bint* fixedbasis, int* verbose, + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_lknetf_alloc( + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_lknetf_config(int* subtype, + int* verbose) noexcept nogil; + +cdef extern void c__pdaf_lknetf_set_iparam(int* id, int* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_lknetf_set_rparam(int* id, double* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_lknetf_options() noexcept nogil; + +cdef extern void c__pdaf_lknetf_memtime( + int* printtype) noexcept nogil; + +cdef extern void c__pdaf_lknetf_alpha_neff(int* dim_ens, double* weights, + double* hlimit, double* alpha) noexcept nogil; + +cdef extern void c__pdaf_lknetf_compute_gamma(int* domain_p, int* step, + int* dim_obs_l, int* dim_ens, double* hx_l, double* hxbar_l, + double* obs_l, int* type_hyb, double* hyb_g, double* hyb_k, + double* gamma, double* n_eff_out, double* skew_mabs, double* kurt_mabs, + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + int* screen, int* flag) noexcept nogil; + +cdef extern void c__pdaf_lknetf_set_gamma(int* domain_p, int* dim_obs_l, + int* dim_ens, double* hx_l, double* hxbar_l, double* weights, + int* type_hyb, double* hyb_g, double* hyb_k, double* gamma, + double* n_eff_out, double* maskew, double* makurt, int* screen, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_lknetf_reset_gamma( + double* gamma_in) noexcept nogil; + +cdef extern void c__pdafhyb3dvar_analysis_cvt(int* step, int* dim_p, + int* dim_obs_p, int* dim_ens, int* dim_cvec, int* dim_cvec_ens, + double* beta_3dvar, double* state_p, double* ens_p, + double* state_inc_p, double* hxbar_p, double* obs_p, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + int* screen, int* type_opt, int* debug, + int* flag) noexcept nogil; + +cdef extern void c__pdaf3dvar_analysis_cvt(int* step, int* dim_p, + int* dim_obs_p, int* dim_cvec, double* state_p, double* hxbar_p, + double* obs_p, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + int* screen, int* type_opt, int* debug, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_lestkf_init(int* subtype, int* param_int, + int* dim_pint, double* param_real, int* dim_preal, + bint* ensemblefilter, bint* fixedbasis, int* verbose, + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_lestkf_alloc( + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_lestkf_config(int* subtype, + int* verbose) noexcept nogil; + +cdef extern void c__pdaf_lestkf_set_iparam(int* id, int* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_lestkf_set_rparam(int* id, double* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_lestkf_options() noexcept nogil; + +cdef extern void c__pdaf_lestkf_memtime( + int* printtype) noexcept nogil; + +cdef extern void c__pdaf_seik_ana(int* step, int* dim_p, int* dim_obs_p, + int* dim_ens, int* rank, double* state_p, double* uinv, double* ens_p, + double* hl_p, double* hxbar_p, double* obs_p, double* forget, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + int* debug, int* flag) noexcept nogil; + +cdef extern void c__pdaf_seik_resample(int* subtype, int* dim_p, + int* dim_ens, int* rank, double* uinv, double* state_p, double* enst_p, + int* type_sqrt, int* type_trans, int* nm1vsn, int* screen, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_lseik_ana(int* domain_p, int* step, int* dim_l, + int* dim_obs_l, int* dim_ens, int* rank, double* state_l, + double* uinv_l, double* ens_l, double* hl_l, double* hxbar_l, + double* obs_l, double* forget, + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + int* screen, int* debug, int* flag) noexcept nogil; + +cdef extern void c__pdaf_lseik_resample(int* domain_p, int* subtype, + int* dim_l, int* dim_ens, int* rank, double* uinv_l, double* state_l, + double* ens_l, double* omegat_in, int* type_sqrt, int* screen, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_prepost( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafenkf_update(int* step, int* dim_p, int* dim_obs_p, + int* dim_ens, double* state_p, double* ens_p, + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* screen, int* subtype, int* dim_lag, double* sens_p, + int* cnt_maxlag, int* flag) noexcept nogil; + +cdef extern void c__pdaf_init_parallel(int* dim_ens, bint* ensemblefilter, + bint* fixedbasis, int* comm_model, int* in_comm_filter, + int* in_comm_couple, int* in_n_modeltasks, int* in_task_id, + int* screen, int* flag) noexcept nogil; + +cdef extern void c__pdaf_seik_init(int* subtype, int* param_int, + int* dim_pint, double* param_real, int* dim_preal, + bint* ensemblefilter, bint* fixedbasis, int* verbose, + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_seik_alloc( + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_seik_config(int* subtype, + int* verbose) noexcept nogil; + +cdef extern void c__pdaf_seik_set_iparam(int* id, int* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_seik_set_rparam(int* id, double* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_seik_options() noexcept nogil; + +cdef extern void c__pdaf_seik_memtime( + int* printtype) noexcept nogil; + +cdef extern void c__pdafnetf_update(int* step, int* dim_p, int* dim_obs_p, + int* dim_ens, double* state_p, double* ainv, double* ens_p, + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__likelihood_pdaf)(int* , int* , double* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* screen, int* subtype, int* dim_lag, double* sens_p, + int* cnt_maxlag, int* flag) noexcept nogil; + +cdef extern void c__pdaf_seik_ana_newt(int* step, int* dim_p, + int* dim_obs_p, int* dim_ens, int* rank, double* state_p, double* uinv, + double* ens_p, double* hl_p, double* hxbar_p, double* obs_p, + double* forget, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + int* screen, int* debug, int* flag) noexcept nogil; + +cdef extern void c__pdaf_seik_resample_newt(int* subtype, int* dim_p, + int* dim_ens, int* rank, double* uinv, double* state_p, double* ens_p, + int* type_sqrt, int* type_trans, int* nm1vsn, int* screen, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_lenkf_ana_rsm(int* step, int* dim_p, + int* dim_obs_p, int* dim_obs, int* dim_ens, int* rank_ana, double* state_p, + double* ens_p, double* hx_p, double* hxbar_p, double* obs_p, + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + void (*c__localize_covar_pdaf)(int* , int* , double* , double* ), + int* screen, int* debug, int* flag) noexcept nogil; + +cdef extern void c__pdaf_lestkf_ana(int* domain_p, int* step, int* dim_l, + int* dim_obs_l, int* dim_ens, int* rank, double* state_l, + double* ainv_l, double* ens_l, double* hl_l, double* hxbar_l, + double* obs_l, double* omegat_in, double* forget, + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + int* envar_mode, int* type_sqrt, double* ta, int* screen, int* debug, + int* flag) noexcept nogil; + +cdef extern void c__pdaflestkf_update(int* step, int* dim_p, + int* dim_obs_f, int* dim_ens, int* rank, double* state_p, double* ainv, + double* ens_p, + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* screen, int* subtype, int* envar_mode, int* dim_lag, + double* sens_p, int* cnt_maxlag, int* flag) noexcept nogil; + +cdef extern void c__pdaf_lnetf_init(int* subtype, int* param_int, + int* dim_pint, double* param_real, int* dim_preal, + bint* ensemblefilter, bint* fixedbasis, int* verbose, + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_lnetf_alloc( + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_lnetf_config(int* subtype, + int* verbose) noexcept nogil; + +cdef extern void c__pdaf_lnetf_set_iparam(int* id, int* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_lnetf_set_rparam(int* id, double* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_lnetf_options() noexcept nogil; + +cdef extern void c__pdaf_lnetf_memtime( + int* printtype) noexcept nogil; + +cdef extern void c__pdaf_enkf_init(int* subtype, int* param_int, + int* dim_pint, double* param_real, int* dim_preal, + bint* ensemblefilter, bint* fixedbasis, int* verbose, + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_enkf_alloc( + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_enkf_config(int* subtype, + int* verbose) noexcept nogil; + +cdef extern void c__pdaf_enkf_set_iparam(int* id, int* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_enkf_set_rparam(int* id, double* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_enkf_options() noexcept nogil; + +cdef extern void c__pdaf_enkf_memtime( + int* printtype) noexcept nogil; + +cdef extern void c__pdaf_enkf_gather_resid(int* dim_obs, int* dim_obs_p, + int* dim_ens, double* resid_p, + double* resid) noexcept nogil; + +cdef extern void c__pdaf_enkf_obs_ensemble(int* step, int* dim_obs_p, + int* dim_obs, int* dim_ens, double* obsens_p, double* obs_p, + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + int* screen, int* flag) noexcept nogil; + +cdef extern void c__pdafpf_update(int* step, int* dim_p, int* dim_obs_p, + int* dim_ens, double* state_p, double* ainv, double* ens_p, + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__likelihood_pdaf)(int* , int* , double* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* screen, int* subtype, int* flag) noexcept nogil; + +cdef extern void c__pdaf_generate_rndmat(int* dim, double* rndmat, + int* mattype) noexcept nogil; + +cdef extern void c__pdaf_print_domain_stats( + int* n_domains_p) noexcept nogil; + +cdef extern void c__pdaf_init_local_obsstats() noexcept nogil; + +cdef extern void c__pdaf_incr_local_obsstats( + int* dim_obs_l) noexcept nogil; + +cdef extern void c__pdaf_print_local_obsstats(int* screen, + int* n_domains_with_obs) noexcept nogil; + +cdef extern void c__pdaf_seik_matrixt(int* dim, int* dim_ens, + double* a) noexcept nogil; + +cdef extern void c__pdaf_seik_ttimesa(int* rank, int* dim_col, double* a, + double* b) noexcept nogil; + +cdef extern void c__pdaf_seik_omega(int* rank, double* omega, + int* omegatype, int* screen) noexcept nogil; + +cdef extern void c__pdaf_seik_uinv(int* rank, + double* uinv) noexcept nogil; + +cdef extern void c__pdaf_ens_omega(int* seed, int* r, int* dim_ens, + double* omega, double* norm, int* otype, + int* screen) noexcept nogil; + +cdef extern void c__pdaf_estkf_omegaa(int* rank, int* dim_col, double* a, + double* b) noexcept nogil; + +cdef extern void c__pdaf_estkf_aomega(int* dim, int* dim_ens, + double* a) noexcept nogil; + +cdef extern void c__pdaf_subtract_rowmean(int* dim, int* dim_ens, + double* a) noexcept nogil; + +cdef extern void c__pdaf_subtract_colmean(int* dim_ens, int* dim, + double* a) noexcept nogil; + +cdef extern void c__pdaf_add_particle_noise(int* dim_p, int* dim_ens, + double* state_p, double* ens_p, int* type_noise, double* noise_amp, + int* screen) noexcept nogil; + +cdef extern void c__pdaf_inflate_weights(int* screen, int* dim_ens, + double* alpha, double* weights) noexcept nogil; + +cdef extern void c__pdaf_inflate_ens(int* dim, int* dim_ens, + double* meanstate, double* ens, double* forget, + bint* do_ensmean) noexcept nogil; + +cdef extern void c__pdaf_alloc(int* dim_p, int* dim_ens, int* dim_ens_task, + int* dim_es, int* statetask, int* outflag) noexcept nogil; + +cdef extern void c__pdaf_alloc_sens(int* dim_p, int* dim_ens, int* dim_lag, + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_alloc_bias(int* dim_bias_p, int* outflag) noexcept nogil; + +cdef extern void c__pdaf_smoothing(int* dim_p, int* dim_ens, int* dim_lag, + double* ainv, double* sens_p, int* cnt_maxlag, double* forget, + int* screen) noexcept nogil; + +cdef extern void c__pdaf_smoothing_local(int* domain_p, int* step, + int* dim_p, int* dim_l, int* dim_ens, int* dim_lag, double* ainv, + double* ens_l, double* sens_p, int* cnt_maxlag, + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + double* forget, int* screen) noexcept nogil; + +cdef extern void c__pdaf_smoother_shift(int* dim_p, int* dim_ens, + int* dim_lag, double* ens_p, double* sens_p, int* cnt_maxlag, + int* screen) noexcept nogil; + +cdef extern void c__pdaflknetf_update_sync(int* step, int* dim_p, + int* dim_obs_f, int* dim_ens, double* state_p, double* ainv, + double* ens_p, + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* screen, int* subtype, int* flag) noexcept nogil; + +cdef extern void c__pdaf_etkf_ana(int* step, int* dim_p, int* dim_obs_p, + int* dim_ens, double* state_p, double* ainv, double* ens_p, + double* hz_p, double* hxbar_p, double* obs_p, double* forget, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + int* screen, int* type_trans, int* debug, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_letkf_ana(int* domain_p, int* step, int* dim_l, + int* dim_obs_l, int* dim_ens, double* state_l, double* ainv_l, + double* ens_l, double* hz_l, double* hxbar_l, double* obs_l, + double* rndmat, double* forget, + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + int* type_trans, int* screen, int* debug, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_letkf_init(int* subtype, int* param_int, + int* dim_pint, double* param_real, int* dim_preal, + bint* ensemblefilter, bint* fixedbasis, int* verbose, + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_letkf_alloc( + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_letkf_config(int* subtype, + int* verbose) noexcept nogil; + +cdef extern void c__pdaf_letkf_set_iparam(int* id, int* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_letkf_set_rparam(int* id, double* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_letkf_options() noexcept nogil; + +cdef extern void c__pdaf_letkf_memtime( + int* printtype) noexcept nogil; + +cdef extern void c__pdaf_estkf_ana(int* step, int* dim_p, int* dim_obs_p, + int* dim_ens, int* rank, double* state_p, double* ainv, double* ens_p, + double* hl_p, double* hxbar_p, double* obs_p, double* forget, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + int* screen, int* envar_mode, int* type_sqrt, int* type_trans, + double* ta, int* debug, int* flag) noexcept nogil; + +cdef extern void c__pdaf_ensrf_ana(int* step, int* dim_p, int* dim_obs_p, + int* dim_ens, double* state_p, double* ens_p, double* hx_p, + double* hxbar_p, double* obs_p, double* var_obs_p, + void (*c__localize_covar_serial_pdaf)(int* , int* , int* , double* , + double* ), + int* screen, int* debug) noexcept nogil; + +cdef extern void c__pdaf_ensrf_ana_2step(int* step, int* dim_p, + int* dim_obs_p, int* dim_ens, double* state_p, double* ens_p, + double* hx_p, double* hxbar_p, double* obs_p, double* var_obs_p, + void (*c__localize_covar_serial_pdaf)(int* , int* , int* , double* , + double* ), + int* screen, int* debug) noexcept nogil; + +cdef extern void c__pdaflnetf_update(int* step, int* dim_p, int* dim_obs_f, + int* dim_ens, double* state_p, double* ainv, double* ens_p, + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* screen, int* subtype, int* dim_lag, double* sens_p, + int* cnt_maxlag, int* flag) noexcept nogil; + +cdef extern void c__pdaf_seik_ana_trans(int* step, int* dim_p, + int* dim_obs_p, int* dim_ens, int* rank, double* state_p, double* uinv, + double* ens_p, double* hl_p, double* hxbar_p, double* obs_p, + double* forget, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + int* screen, int* type_sqrt, int* type_trans, int* nm1vsn, int* debug, + int* flag) noexcept nogil; + +cdef extern void c__pdafhyb3dvar_update_estkf(int* step, int* dim_p, + int* dim_obs_p, int* dim_ens, int* dim_cvec, int* dim_cvec_ens, + double* state_p, double* ainv, double* ens_p, + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + int* screen, int* flag) noexcept nogil; + +cdef extern void c__pdafhyb3dvar_update_lestkf(int* step, int* dim_p, + int* dim_obs_p, int* dim_ens, int* dim_cvec, int* dim_cvec_ens, + double* state_p, double* ainv, double* ens_p, + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_f_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + int* screen, int* flag) noexcept nogil; + +cdef extern void c__pdaf_lestkf_ana_fixed(int* domain_p, int* step, + int* dim_l, int* dim_obs_l, int* dim_ens, int* rank, double* state_l, + double* ainv_l, double* ens_l, double* hl_l, double* hxbar_l, + double* obs_l, double* forget, + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + int* type_sqrt, int* screen, int* debug, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_genobs_init(int* subtype, int* param_int, + int* dim_pint, double* param_real, int* dim_preal, + bint* ensemblefilter, bint* fixedbasis, int* verbose, + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_genobs_alloc( + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_genobs_config(int* subtype, + int* verbose) noexcept nogil; + +cdef extern void c__pdaf_genobs_set_iparam(int* id, int* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_genobs_options() noexcept nogil; + +cdef extern void c__pdaf_etkf_ana_t(int* step, int* dim_p, int* dim_obs_p, + int* dim_ens, double* state_p, double* ainv, double* ens_p, + double* hz_p, double* hxbar_p, double* obs_p, double* forget, + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + int* screen, int* type_trans, int* debug, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_letkf_ana_fixed(int* domain_p, int* step, + int* dim_l, int* dim_obs_l, int* dim_ens, double* state_l, + double* ainv_l, double* ens_l, double* hz_l, double* hxbar_l, + double* obs_l, double* forget, + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + int* screen, int* debug, int* flag) noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/PDAF/internal.pyx b/pyPDAF/source/src/pyPDAF/PDAF/internal.pyx new file mode 100644 index 0000000000000000000000000000000000000000..e06c709436ed06044428cb169ebda0ca87748a3c --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/internal.pyx @@ -0,0 +1,19233 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + +try: + import mpi4py + mpi4py.rc.initialize = False +except ImportError: + pass + +# Global error handler +def global_except_hook(exctype, value, traceback): + from traceback import print_exception + try: + import mpi4py.MPI + + if mpi4py.MPI.Is_initialized(): + try: + sys.stderr.write('Uncaught exception was ''detected on rank {}.\n'.format( + mpi4py.MPI.COMM_WORLD.Get_rank())) + print_exception(exctype, value, traceback) + sys.stderr.write("\n") + sys.stderr.flush() + finally: + try: + mpi4py.MPI.COMM_WORLD.Abort(1) + except Exception as e: + sys.stderr.write('MPI Abort failed, this process will hang.\n') + sys.stderr.flush() + raise e + else: + sys.__excepthook__(exctype, value, traceback) + except ImportError: + sys.__excepthook__(exctype, value, traceback) + +sys.excepthook = global_except_hook + +def mpi_init(): + """Initialise MPI + """ + with nogil: + c__pdaf_mpi_init() + +def timeit(int timerid, str operation): + """PDAF timer + + Parameters + ---------- + timerid : int + Timer ID + operation : str + Operation name + """ + operation_byte = operation.encode('UTF-8') + cdef char* operation_ptr = operation_byte + with nogil: + c__pdaf_timeit(&timerid, operation_ptr) + +def set_forget(int step, int localfilter, int dim_obs_p, int dim_ens, + double [::1,:] mens_p, double [::1] mstate_p, double [::1] obs_p, + py__init_obsvar_pdaf, double forget_in, int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + localfilter : int + Whether filter is domain-local + dim_obs_p : int + Dimension of observation vector + dim_ens : int + Ensemble size + mens_p : ndarray[np.float64, ndim=2] + Observed PE-local ensemble + Array shape: (dim_obs_p, dim_ens) + mstate_p : ndarray[np.float64, ndim=1] + Observed PE-local mean state + Array shape: (dim_obs_p) + obs_p : ndarray[np.float64, ndim=1] + Observation vector + Array shape: (dim_obs_p) + py__init_obsvar_pdaf : Callable + Initialize mean obs. error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + forget_in : double + Prescribed forgetting factor + screen : int + Verbosity flag + + Returns + ------- + forget_out : double + Adaptively estimated forgetting factor + """ + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + cdef double forget_out + with nogil: + c__pdaf_set_forget(&step, &localfilter, &dim_obs_p, &dim_ens, + &mens_p[0,0], &mstate_p[0], &obs_p[0], + pdaf_cb.c__init_obsvar_pdaf, &forget_in, + &forget_out, &screen) + + return forget_out + +def set_iparam_filters(int id, int value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : int + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_set_iparam_filters(&id, &value, &flag) + + return flag + + +def set_rparam_filters(int id, double value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : double + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_set_rparam_filters(&id, &value, &flag) + + return flag + +def set_forget_local(int domain, int step, int dim_obs_l, int dim_ens, + double [::1,:] hx_l, double [::1] hxbar_l, double [::1] obs_l, + py__init_obsvar_l_pdaf, double forget): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain : int + Current local analysis domain + step : int + Current time step + dim_obs_l : int + Dimension of local observation vector + dim_ens : int + Ensemble size + hx_l : ndarray[np.float64, ndim=2] + Local observed ensemble + Array shape: (dim_obs_l, dim_ens) + hxbar_l : ndarray[np.float64, ndim=1] + Local observed state estimate + Array shape: (dim_obs_l) + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_l) + py__init_obsvar_l_pdaf : Callable + Initialize local mean obs. error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + forget : double + Prescribed forgetting factor + + Returns + ------- + aforget : double + Adaptive forgetting factor + """ + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + cdef double aforget + with nogil: + c__pdaf_set_forget_local(&domain, &step, &dim_obs_l, &dim_ens, + &hx_l[0,0], &hxbar_l[0], &obs_l[0], + pdaf_cb.c__init_obsvar_l_pdaf, &forget, + &aforget) + + return aforget + + +def fcst_operations(int step, py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Time step in current forecast phase + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + with nogil: + c__pdaf_fcst_operations(&step, pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, &outflag) + + return outflag + + +def letkf_ana_t(int domain_p, int step, int dim_l, int dim_obs_l, + int dim_ens, double [::1] state_l, double [::1,:] ens_l, + double [::1,:] hz_l, double [::1] hxbar_l, double [::1] obs_l, + double [::1,:] rndmat, double forget, py__prodrinva_l_pdaf, + int type_trans, int screen, int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + step : int + Current time step + dim_l : int + State dimension on local analysis domain + dim_obs_l : int + Size of obs. vector on local ana. domain + dim_ens : int + Size of ensemble + state_l : ndarray[np.float64, ndim=1] + Local forecast state + Array shape: (dim_l) + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + hz_l : ndarray[np.float64, ndim=2] + Local observed state ensemble (perturbation) + Array shape: (dim_obs_l, dim_ens) + hxbar_l : ndarray[np.float64, ndim=1] + Local observed ensemble mean + Array shape: (dim_obs_l) + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_l) + rndmat : ndarray[np.float64, ndim=2] + Global random rotation matrix + Array shape: (dim_ens, dim_ens) + forget : double + Forgetting factor + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A for local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + type_trans : int + Type of ensemble transformation + screen : int + Verbosity flag + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_l : ndarray[np.float64, ndim=1] + Local forecast state + Array shape: (dim_l) + ainv_l : ndarray[np.float64, ndim=2] + on exit: local weight matrix for ensemble transformation + Array shape: (dim_ens, dim_ens) + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + hz_l : ndarray[np.float64, ndim=2] + Local observed state ensemble (perturbation) + Array shape: (dim_obs_l, dim_ens) + rndmat : ndarray[np.float64, ndim=2] + Global random rotation matrix + Array shape: (dim_ens, dim_ens) + forget : double + Forgetting factor + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_l_np = np.asarray(state_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_l_np = np.zeros((dim_ens, dim_ens), dtype=np.float64, order="F") + cdef double [::1,:] ainv_l = ainv_l_np + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_l_np = np.asarray(ens_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hz_l_np = np.asarray(hz_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] rndmat_np = np.asarray(rndmat, dtype=np.float64, order="F") + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + with nogil: + c__pdaf_letkf_ana_t(&domain_p, &step, &dim_l, &dim_obs_l, &dim_ens, + &state_l[0], &ainv_l[0,0], &ens_l[0,0], + &hz_l[0,0], &hxbar_l[0], &obs_l[0], + &rndmat[0,0], &forget, + pdaf_cb.c__prodrinva_l_pdaf, &type_trans, + &screen, &debug, &flag) + + return state_l_np, ainv_l_np, ens_l_np, hz_l_np, rndmat_np, forget, flag + + +def seik_update(int step, int dim_p, int dim_ens, int rank, + double [::1] state_p, double [::1,:] uinv, double [::1,:] ens_p, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__prodrinva_pdaf, py__init_obsvar_pdaf, py__prepoststep_pdaf, + int screen, int subtype, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + rank : int + Rank of initial covariance matrix + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (rank, rank) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A for SEIK analysis + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + screen : int + Verbosity flag + subtype : int + Filter subtype + flag : int + Status flag + + Returns + ------- + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (rank, rank) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] uinv_np = np.asarray(uinv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int dim_obs_p + with nogil: + c__pdafseik_update(&step, &dim_p, &dim_obs_p, &dim_ens, &rank, + &state_p[0], &uinv[0,0], &ens_p[0,0], + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__prepoststep_pdaf, &screen, &subtype, + &flag) + + return dim_obs_p, state_p_np, uinv_np, ens_p_np, flag + + +def _3dvar_update(int step, int dim_p, int dim_ens, int dim_cvec, + double [::1] state_p, double [::1,:] ainv, double [::1,:] ens_p, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__prodrinva_pdaf, py__prepoststep_pdaf, py__cvt_pdaf, + py__cvt_adj_pdaf, py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, + int screen, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + dim_cvec : int + Size of control vector (parameterized part) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Not used in 3D-Var + Array shape: (1, 1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A for 3DVAR analysis + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__cvt_pdaf : Callable + Apply control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + screen : int + Verbosity flag + subtype : int + Filter subtype + flag : int + Status flag + + Returns + ------- + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Not used in 3D-Var + Array shape: (1, 1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_np = np.asarray(ainv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + cdef int dim_obs_p + with nogil: + c__pdaf3dvar_update(&step, &dim_p, &dim_obs_p, &dim_ens, &dim_cvec, + &state_p[0], &ainv[0,0], &ens_p[0,0], + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__cvt_pdaf, pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, &screen, + &flag) + + return dim_obs_p, state_p_np, ainv_np, ens_p_np, flag + + +def en3dvar_update_estkf(int step, int dim_p, int dim_ens, + int dim_cvec_ens, double [::1] state_p, double [::1,:] ainv, + double [::1,:] ens_p, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__prodrinva_pdaf, py__prepoststep_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__init_obsvar_pdaf, int screen, + int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + dim_cvec_ens : int + Size of control vector (ensemble part) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Transform matrix + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A for 3DVAR analysis + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble var) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + screen : int + Verbosity flag + flag : int + Status flag + + Returns + ------- + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Transform matrix + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_np = np.asarray(ainv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + cdef int dim_obs_p + with nogil: + c__pdafen3dvar_update_estkf(&step, &dim_p, &dim_obs_p, &dim_ens, + &dim_cvec_ens, &state_p[0], &ainv[0,0], + &ens_p[0,0], + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_obsvar_pdaf, &screen, + &flag) + + return dim_obs_p, state_p_np, ainv_np, ens_p_np, flag + + +def en3dvar_update_lestkf(int step, int dim_p, int dim_ens, + int dim_cvec_ens, double [::1] state_p, double [::1,:] ainv, + double [::1,:] ens_p, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__prodrinva_pdaf, py__prepoststep_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, + py__init_obs_f_pdaf, py__init_obs_l_pdaf, py__prodrinva_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__g2l_obs_pdaf, py__init_obsvar_pdaf, py__init_obsvar_l_pdaf, + int screen, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + dim_cvec_ens : int + Size of control vector (ensemble part) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Transform matrix + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A for 3DVAR analysis + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble var) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_f_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Size of the full observation vector + + Callback Returns + ---------------- + observation_f : ndarray[np.float64, ndim=1] + Full vector of observations + Array shape: (dim_obs_f) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + screen : int + Verbosity flag + flag : int + Status flag + + Returns + ------- + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Transform matrix + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_np = np.asarray(ainv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.init_obs_f_pdaf = py__init_obs_f_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + cdef int dim_obs_p + with nogil: + c__pdafen3dvar_update_lestkf(&step, &dim_p, &dim_obs_p, &dim_ens, + &dim_cvec_ens, &state_p[0], + &ainv[0,0], &ens_p[0,0], + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__init_obs_f_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + &screen, &flag) + + return dim_obs_p, state_p_np, ainv_np, ens_p_np, flag + + +def etkf_update(int step, int dim_p, int dim_ens, double [::1] state_p, + double [::1,:] ainv, double [::1,:] ens_p, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__prodrinva_pdaf, + py__init_obsvar_pdaf, py__prepoststep_pdaf, int screen, int subtype, + int dim_lag, double [::1,:,:] sens_p, int cnt_maxlag, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (dim_ens, dim_ens) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A for ETKF analysis + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + screen : int + Verbosity flag + subtype : int + Filter subtype + dim_lag : int + Number of past time instances for smoother + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count number of past time steps for smoothing + flag : int + Status flag + + Returns + ------- + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (dim_ens, dim_ens) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count number of past time steps for smoothing + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_np = np.asarray(ainv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=3, mode="fortran", negative_indices=False, cast=False] sens_p_np = np.asarray(sens_p, dtype=np.float64, order="F") + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int dim_obs_p + with nogil: + c__pdafetkf_update(&step, &dim_p, &dim_obs_p, &dim_ens, + &state_p[0], &ainv[0,0], &ens_p[0,0], + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__prepoststep_pdaf, &screen, &subtype, + &dim_lag, &sens_p[0,0,0], &cnt_maxlag, &flag) + + return dim_obs_p, state_p_np, ainv_np, ens_p_np, sens_p_np, cnt_maxlag, flag + + +def netf_ana(int step, int dim_p, int dim_obs_p, int dim_ens, + double [::1,:] ens_p, double [::1,:] rndmat, double [::1,:] t, + int type_forget, double forget, int type_winf, double limit_winf, + int type_noise, double noise_amp, double [::1,:] hz_p, + double [::1] obs_p, py__likelihood_pdaf, int screen, int debug, + int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_obs_p : int + PE-local dimension of observation vector + dim_ens : int + Size of ensemble + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + rndmat : ndarray[np.float64, ndim=2] + Orthogonal random matrix + Array shape: (dim_ens, dim_ens) + t : ndarray[np.float64, ndim=2] + Ensemble transform matrix + Array shape: (dim_ens, dim_ens) + type_forget : int + Type of forgetting factor + forget : double + Forgetting factor + type_winf : int + Type of weights inflation + limit_winf : double + Limit for weights inflation + type_noise : int + Type of pertubing noise + noise_amp : double + Amplitude of noise + hz_p : ndarray[np.float64, ndim=2] + Temporary matrices for analysis + Array shape: (dim_obs_p, dim_ens) + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + py__likelihood_pdaf : Callable + Compute observation likelihood for an ensemble member + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + resid : ndarray[np.float64, ndim=1] + Input vector holding the residual + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + likely : double + Output value of the likelihood + + screen : int + Verbosity flag + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + PE-local forecast state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + t : ndarray[np.float64, ndim=2] + Ensemble transform matrix + Array shape: (dim_ens, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.zeros((dim_p), dtype=np.float64, order="F") + cdef double [::1] state_p = state_p_np + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] t_np = np.asarray(t, dtype=np.float64, order="F") + pdaf_cb.likelihood_pdaf = py__likelihood_pdaf + with nogil: + c__pdaf_netf_ana(&step, &dim_p, &dim_obs_p, &dim_ens, &state_p[0], + &ens_p[0,0], &rndmat[0,0], &t[0,0], &type_forget, + &forget, &type_winf, &limit_winf, &type_noise, + &noise_amp, &hz_p[0,0], &obs_p[0], + pdaf_cb.c__likelihood_pdaf, &screen, &debug, &flag) + + return state_p_np, ens_p_np, t_np, flag + + +def netf_smoothert(int step, int dim_p, int dim_obs_p, int dim_ens, + double [::1,:] ens_p, double [::1,:] rndmat, double [::1,:] ta, + double [::1,:] hx_p, double[::1] obs_p, + py__likelihood_pdaf, int screen, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_obs_p: int + PE-local dimension of observation vector + dim_ens : int + Size of ensemble + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + rndmat : ndarray[np.float64, ndim=2] + Orthogonal random matrix + Array shape: (dim_ens, dim_ens) + ta : ndarray[np.float64, ndim=2] + Ensemble transform matrix + Array shape: (dim_ens, dim_ens) + hx_p : ndarray[np.float64, ndim=1] + Temporary matrices for analysis + Array shape: (dim_p) + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + py__likelihood_pdaf : Callable + Compute observation likelihood for an ensemble member + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + resid : ndarray[np.float64, ndim=1] + Input vector holding the residual + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + likely : double + Output value of the likelihood + + screen : int + Verbosity flag + flag : int + Status flag + + Returns + ------- + dim_obs_p : int + PE-local dimension of observation vector + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + t : ndarray[np.float64, ndim=2] + Ensemble transform matrix + Array shape: (dim_ens, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ta_np = np.asarray(ta, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hx_p_np = np.asarray(hx_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obs_p_np = np.asarray(obs_p, dtype=np.float64, order="F") + + pdaf_cb.likelihood_pdaf = py__likelihood_pdaf + + with nogil: + c__pdaf_netf_smoothert(&step, &dim_p, &dim_obs_p, &dim_ens, + &ens_p[0,0], &rndmat[0,0], &ta[0,0], + &hx_p[0,0], &obs_p[0], + pdaf_cb.c__likelihood_pdaf, &screen, &flag) + + return ens_p_np, ta_np, flag + + +def smoother_netf(int dim_p, int dim_ens, int dim_lag, + double [::1,:] ainv, double [::1,:,:] sens_p, int cnt_maxlag, int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + dim_lag : int + Number of past time instances for smoother + ainv : ndarray[np.float64, ndim=2] + Weight matrix for ensemble transformation + Array shape: (dim_ens, dim_ens) + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count available number of time steps for smoothing + screen : int + Verbosity flag + + Returns + ------- + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count available number of time steps for smoothing + """ + cdef cnp.ndarray[cnp.float64_t, ndim=3, mode="fortran", negative_indices=False, cast=False] sens_p_np = np.asarray(sens_p, dtype=np.float64, order="F") + with nogil: + c__pdaf_smoother_netf(&dim_p, &dim_ens, &dim_lag, &ainv[0,0], + &sens_p[0,0,0], &cnt_maxlag, &screen) + + return sens_p_np, cnt_maxlag + + +def lnetf_ana(int domain_p, int step, int dim_l, int dim_obs_l, + int dim_ens, double [::1,:] ens_l, double [::1,:] hx_l, + double [::1] obs_l, double [::1,:] rndmat, py__likelihood_l_pdaf, + int type_forget, double forget, int type_winf, double limit_winf, + int cnt_small_svals, double [::1] eff_dimens, double [::1,:] t, + int screen, int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + step : int + Current time step + dim_l : int + State dimension on local analysis domain + dim_obs_l : int + Size of obs. vector on local ana. domain + dim_ens : int + Size of ensemble + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + hx_l : ndarray[np.float64, ndim=2] + Local observed state ensemble (perturbation) + Array shape: (dim_obs_l, dim_ens) + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_l) + rndmat : ndarray[np.float64, ndim=2] + Global random rotation matrix + Array shape: (dim_ens, dim_ens) + py__likelihood_l_pdaf : Callable + Compute observation likelihood for an ensemble member + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + type_forget : int + Typ eof forgetting factor + forget : double + Forgetting factor + type_winf : int + Type of weights inflation + limit_winf : double + Limit for weights inflation + cnt_small_svals : int + Number of small eigen values + eff_dimens : ndarray[np.float64, ndim=1] + Effective ensemble size + Array shape: (1) + t : ndarray[np.float64, ndim=2] + local ensemble transformation matrix + Array shape: (dim_ens, dim_ens) + screen : int + Verbosity flag + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + cnt_small_svals : int + Number of small eigen values + eff_dimens : ndarray[np.float64, ndim=1] + Effective ensemble size + Array shape: (1) + t : ndarray[np.float64, ndim=2] + local ensemble transformation matrix + Array shape: (dim_ens, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_l_np = np.asarray(ens_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] eff_dimens_np = np.asarray(eff_dimens, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] t_np = np.asarray(t, dtype=np.float64, order="F") + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + with nogil: + c__pdaf_lnetf_ana(&domain_p, &step, &dim_l, &dim_obs_l, &dim_ens, + &ens_l[0,0], &hx_l[0,0], &obs_l[0], &rndmat[0,0], + pdaf_cb.c__likelihood_l_pdaf, &type_forget, + &forget, &type_winf, &limit_winf, + &cnt_small_svals, &eff_dimens[0], &t[0,0], + &screen, &debug, &flag) + + return ens_l_np, cnt_small_svals, eff_dimens_np, t_np, flag + + +def lnetf_smoothert(int domain_p, int step, int dim_obs_f, + int dim_obs_l, int dim_ens, double [::1,:] hx_f, + double [::1,:] rndmat, py__g2l_obs_pdaf, py__init_obs_l_pdaf, + py__likelihood_l_pdaf, int screen, double [::1,:] t, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + step : int + Current time step + dim_obs_f : int + PE-local dimension of full observation vector + dim_obs_l : int + Size of obs. vector on local ana. domain + dim_ens : int + Size of ensemble + hx_f : ndarray[np.float64, ndim=2] + PE-local full observed state ens. + Array shape: (dim_obs_f, dim_ens) + rndmat : ndarray[np.float64, ndim=2] + Global random rotation matrix + Array shape: (dim_ens, dim_ens) + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__likelihood_l_pdaf : Callable + Compute observation likelihood for an ensemble member + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + screen : int + Verbosity flag + t : ndarray[np.float64, ndim=2] + local ensemble transformation matrix + Array shape: (dim_ens, dim_ens) + flag : int + Status flag + + Returns + ------- + t : ndarray[np.float64, ndim=2] + local ensemble transformation matrix + Array shape: (dim_ens, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] t_np = np.asarray(t, dtype=np.float64, order="F") + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + with nogil: + c__pdaf_lnetf_smoothert(&domain_p, &step, &dim_obs_f, &dim_obs_l, + &dim_ens, &hx_f[0,0], &rndmat[0,0], + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, &screen, + &t[0,0], &flag) + + return t_np, flag + + +def smoother_lnetf(int domain_p, int step, int dim_p, int dim_l, + int dim_ens, int dim_lag, double [::1,:] ainv, double [::1,:] ens_l, + double [::1,:,:] sens_p, int cnt_maxlag, py__g2l_state_pdaf, + py__l2g_state_pdaf, int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_l : int + State dimension on local analysis domain + dim_ens : int + Size of ensemble + dim_lag : int + Number of past time instances for smoother + ainv : ndarray[np.float64, ndim=2] + Weight matrix for ensemble transformation + Array shape: (dim_ens, dim_ens) + ens_l : ndarray[np.float64, ndim=2] + local past ensemble (temporary) + Array shape: (dim_l, dim_ens) + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count available number of time steps for smoothing + py__g2l_state_pdaf : Callable + Get state on local ana. domain from global state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + screen : int + Verbosity flag + + Returns + ------- + ens_l : ndarray[np.float64, ndim=2] + local past ensemble (temporary) + Array shape: (dim_l, dim_ens) + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count available number of time steps for smoothing + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_l_np = np.asarray(ens_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=3, mode="fortran", negative_indices=False, cast=False] sens_p_np = np.asarray(sens_p, dtype=np.float64, order="F") + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + with nogil: + c__pdaf_smoother_lnetf(&domain_p, &step, &dim_p, &dim_l, &dim_ens, + &dim_lag, &ainv[0,0], &ens_l[0,0], + &sens_p[0,0,0], &cnt_maxlag, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, &screen) + + return ens_l_np, sens_p_np, cnt_maxlag + + +def memcount_ini(int ncounters): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + ncounters : int + Number of memory counters + + Returns + ------- + """ + with nogil: + c__pdaf_memcount_ini(&ncounters) + + + +def memcount_define(str stortype, int wordlength): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + stortype : char + Type of variable + wordlength : int + Word length for chosen type + + Returns + ------- + """ + stortype_byte = stortype.encode('UTF-8') + cdef char* stortype_ptr = stortype_byte + with nogil: + c__pdaf_memcount_define(stortype_ptr, &wordlength) + + + +def memcount(int id, str stortype, int dim): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Id of the counter + stortype : char + Type of variable + dim : int + Dimension of allocated variable + + Returns + ------- + """ + stortype_byte = stortype.encode('UTF-8') + cdef char* stortype_ptr = stortype_byte + with nogil: + c__pdaf_memcount(&id, stortype_ptr, &dim) + + + +def init_filters(int type_filter, int subtype, int [::1] param_int, + int dim_pint, double [::1] param_real, int dim_preal, int screen, + int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + type_filter : int + Type of filter + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + dim_pint : int + Number of integer parameters + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + dim_preal : int + Number of real parameters + screen : int + Control screen output + flag : int + Status flag + + Returns + ------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + filterstr : char + Name of filter algorithm + ensemblefilter : bint + Is the chosen filter ensemble-based? + fixedbasis : bint + Does the filter run with fixed error-space basis? + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_int_np = np.asarray(param_int, dtype=np.intc, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_real_np = np.asarray(param_real, dtype=np.float64, order="F") + cdef char* filterstr_ptr + cdef str filterstr + cdef bint ensemblefilter + cdef bint fixedbasis + with nogil: + c__pdaf_init_filters(&type_filter, &subtype, ¶m_int[0], + &dim_pint, ¶m_real[0], &dim_preal, + filterstr_ptr, &ensemblefilter, &fixedbasis, + &screen, &flag) + filterstr = filterstr_ptr.decode('UTF-8') + return subtype, param_int_np, param_real_np, filterstr, ensemblefilter, fixedbasis, flag + + +def alloc_filters(str filterstr, int subtype, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + filterstr : char + Name of filter algorithm + subtype : int + Sub-type of filter + flag : int + Status flag + + Returns + ------- + flag : int + Status flag + """ + filterstr_byte = filterstr.encode('UTF-8') + cdef char* filterstr_ptr = filterstr_byte + with nogil: + c__pdaf_alloc_filters(filterstr_ptr, &subtype, &flag) + + return flag + + +def configinfo_filters(int subtype, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + verbose : int + Control screen output + + Returns + ------- + subtype : int + Sub-type of filter + """ + with nogil: + c__pdaf_configinfo_filters(&subtype, &verbose) + + return subtype + + +def options_filters(int type_filter): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + type_filter : int + Type of filter + + Returns + ------- + """ + with nogil: + c__pdaf_options_filters(&type_filter) + + + +def print_info_filters(int printtype): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + printtype : int + Type of screen output: + + Returns + ------- + """ + with nogil: + c__pdaf_print_info_filters(&printtype) + +def allreduce(int val_p, int mpitype, int mpiop): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + val_p : int + PE-local value + mpitype : int + MPI data type + mpiop : int + MPI operator + + Returns + ------- + val_g : int + reduced global value + status : int + Status flag: (0) no error + """ + cdef int val_g + cdef int status + with nogil: + c__pdaf_allreduce(&val_p, &val_g, &mpitype, &mpiop, &status) + + return val_g, status + + +def lseik_update(int step, int dim_p, int dim_ens, int rank, + double [::1] state_p, double [::1,:] uinv, double [::1,:] ens_p, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__init_obs_l_pdaf, py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, + py__l2g_state_pdaf, py__g2l_obs_pdaf, py__init_obsvar_pdaf, + py__init_obsvar_l_pdaf, py__prepoststep_pdaf, int screen, + int subtype, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + rank : int + Rank of initial covariance matrix + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (rank, rank) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prodrinva_l_pdaf : Callable + Compute product of R^(-1) with HV + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from global state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + screen : int + Verbosity flag + subtype : int + Filter subtype + flag : int + Status flag + + Returns + ------- + dim_obs_f : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (rank, rank) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] uinv_np = np.asarray(uinv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int dim_obs_f + with nogil: + c__pdaflseik_update(&step, &dim_p, &dim_obs_f, &dim_ens, &rank, + &state_p[0], &uinv[0,0], &ens_p[0,0], + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, &screen, &subtype, + &flag) + + return dim_obs_f, state_p_np, uinv_np, ens_p_np, flag + + +def ensrf_init(int subtype, int [::1] param_int, int dim_pint, + double [::1] param_real, int dim_preal, int verbose, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + dim_pint : int + Number of integer parameters + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + dim_preal : int + Number of real parameters + verbose : int + Control screen output + outflag : int + Status flag + + Returns + ------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + ensemblefilter : bint + Is the chosen filter ensemble-based? + fixedbasis : bint + Does the filter run with fixed error-space basis? + outflag : int + Status flag + """ + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_int_np = np.asarray(param_int, dtype=np.intc, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_real_np = np.asarray(param_real, dtype=np.float64, order="F") + cdef bint ensemblefilter + cdef bint fixedbasis + with nogil: + c__pdaf_ensrf_init(&subtype, ¶m_int[0], &dim_pint, + ¶m_real[0], &dim_preal, &ensemblefilter, + &fixedbasis, &verbose, &outflag) + + return subtype, param_int_np, param_real_np, ensemblefilter, fixedbasis, outflag + + +def ensrf_alloc(int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + with nogil: + c__pdaf_ensrf_alloc(&outflag) + + return outflag + + +def ensrf_config(int subtype, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + verbose : int + Control screen output + + Returns + ------- + subtype : int + Sub-type of filter + """ + with nogil: + c__pdaf_ensrf_config(&subtype, &verbose) + + return subtype + + +def ensrf_set_iparam(int id, int value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : int + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_ensrf_set_iparam(&id, &value, &flag) + + return flag + + +def ensrf_set_rparam(int id, double value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : double + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_ensrf_set_rparam(&id, &value, &flag) + + return flag + + +def ensrf_options(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdaf_ensrf_options() + + + +def ensrf_memtime(int printtype): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + printtype : int + Type of screen output: + + Returns + ------- + """ + with nogil: + c__pdaf_ensrf_memtime(&printtype) + + + +def estkf_ana_fixed(int step, int dim_p, int dim_obs_p, int dim_ens, + int rank, double [::1] state_p, double [::1,:] ainv, + double [::1,:] ens_p, double [::1,:] hl_p, double [::1] hxbar_p, + double [::1] obs_p, double forget, py__prodrinva_pdaf, int screen, + int type_sqrt, int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_obs_p : int + PE-local dimension of observation vector + dim_ens : int + Size of ensemble + rank : int + Rank of initial covariance matrix + state_p : ndarray[np.float64, ndim=1] + on exit: PE-local forecast mean state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix A - temporary use only + Array shape: (rank, rank) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hl_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble + Array shape: (dim_obs_p, dim_ens) + hxbar_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + forget : double + Forgetting factor + py__prodrinva_pdaf : Callable + Provide product R^-1 with some matrix + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + screen : int + Verbosity flag + type_sqrt : int + Type of square-root of A + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + on exit: PE-local forecast mean state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix A - temporary use only + Array shape: (rank, rank) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hl_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble + Array shape: (dim_obs_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_np = np.asarray(ainv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hl_p_np = np.asarray(hl_p, dtype=np.float64, order="F") + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + with nogil: + c__pdaf_estkf_ana_fixed(&step, &dim_p, &dim_obs_p, &dim_ens, &rank, + &state_p[0], &ainv[0,0], &ens_p[0,0], + &hl_p[0,0], &hxbar_p[0], &obs_p[0], + &forget, pdaf_cb.c__prodrinva_pdaf, + &screen, &type_sqrt, &debug, &flag) + + return state_p_np, ainv_np, ens_p_np, hl_p_np, flag + + +def etkf_ana_fixed(int step, int dim_p, int dim_obs_p, int dim_ens, + double [::1,:] ens_p, double [::1,:] hz_p, double [::1] hxbar_p, + double [::1] obs_p, double forget, py__prodrinva_pdaf, int screen, + int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_obs_p : int + PE-local dimension of observation vector + dim_ens : int + Size of ensemble + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hz_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble + Array shape: (dim_obs_p, dim_ens) + hxbar_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + forget : double + Forgetting factor + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + screen : int + Verbosity flag + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + on exit: PE-local forecast state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + on exit: weight matrix for ensemble transformation + Array shape: (dim_ens, dim_ens) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hz_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble + Array shape: (dim_obs_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.zeros((dim_p), dtype=np.float64, order="F") + cdef double [::1] state_p = state_p_np + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_np = np.zeros((dim_ens, dim_ens), dtype=np.float64, order="F") + cdef double [::1,:] ainv = ainv_np + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hz_p_np = np.asarray(hz_p, dtype=np.float64, order="F") + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + with nogil: + c__pdaf_etkf_ana_fixed(&step, &dim_p, &dim_obs_p, &dim_ens, + &state_p[0], &ainv[0,0], &ens_p[0,0], + &hz_p[0,0], &hxbar_p[0], &obs_p[0], &forget, + pdaf_cb.c__prodrinva_pdaf, &screen, &debug, + &flag) + + return state_p_np, ainv_np, ens_p_np, hz_p_np, flag + + +def estkf_update(int step, int dim_p, int dim_ens, + double [::1] state_p, double [::1,:] ainv, double [::1,:] ens_p, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__prodrinva_pdaf, py__init_obsvar_pdaf, py__prepoststep_pdaf, + int screen, int subtype, int envar_mode, int dim_lag, + double [::1,:,:] sens_p, int cnt_maxlag, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of transform matrix A + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A for ESTKF analysis + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + screen : int + Verbosity flag + subtype : int + Filter subtype + envar_mode : int + Flag whether routine is called from 3DVar for special functionality + dim_lag : int + Number of past time instances for smoother + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count number of past time steps for smoothing + flag : int + Status flag + + Returns + ------- + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of transform matrix A + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count number of past time steps for smoothing + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_np = np.asarray(ainv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=3, mode="fortran", negative_indices=False, cast=False] sens_p_np = np.asarray(sens_p, dtype=np.float64, order="F") + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int dim_obs_p + with nogil: + c__pdafestkf_update(&step, &dim_p, &dim_obs_p, &dim_ens, + &state_p[0], &ainv[0,0], &ens_p[0,0], + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__prepoststep_pdaf, &screen, &subtype, + &envar_mode, &dim_lag, &sens_p[0,0,0], + &cnt_maxlag, &flag) + + return dim_obs_p, state_p_np, ainv_np, ens_p_np, sens_p_np, cnt_maxlag, flag + + +def lknetf_update_step(int step, int dim_p, int dim_ens, + double [::1] state_p, double [::1,:] ainv, double [::1,:] ens_p, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__init_obs_l_pdaf, py__prodrinva_hyb_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__g2l_obs_pdaf, py__init_obsvar_pdaf, py__init_obsvar_l_pdaf, + py__likelihood_l_pdaf, py__likelihood_hyb_l_pdaf, py__prepoststep_pdaf, + int screen, int subtype, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (dim_ens, dim_ens) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prodrinva_hyb_l_pdaf : Callable + Compute product of R^(-1) with HV with hybrid weight + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + dim_ens : int + Number of the columns in the matrix processes here. This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from global state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__likelihood_l_pdaf : Callable + Compute likelihood + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__likelihood_hyb_l_pdaf : Callable + Compute likelihood with hybrid weight + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + screen : int + Verbosity flag + subtype : int + Filter subtype + flag : int + Status flag + + Returns + ------- + dim_obs_f : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (dim_ens, dim_ens) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_np = np.asarray(ainv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prodrinva_hyb_l_pdaf = py__prodrinva_hyb_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.likelihood_hyb_l_pdaf = py__likelihood_hyb_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int dim_obs_f + with nogil: + c__pdaflknetf_update_step(&step, &dim_p, &dim_obs_f, &dim_ens, + &state_p[0], &ainv[0,0], &ens_p[0,0], + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prodrinva_hyb_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__likelihood_hyb_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, &screen, + &subtype, &flag) + + return dim_obs_f, state_p_np, ainv_np, ens_p_np, flag + + +def letkf_update(int step, int dim_p, int dim_ens, + double [::1] state_p, double [::1,:] ainv, double [::1,:] ens_p, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__init_obs_l_pdaf, py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, + py__l2g_state_pdaf, py__g2l_obs_pdaf, py__init_obsvar_pdaf, + py__init_obsvar_l_pdaf, py__prepoststep_pdaf, int screen, + int subtype, int dim_lag, double [::1,:,:] sens_p, int cnt_maxlag, + int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (dim_ens, dim_ens) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + screen : int + Verbosity flag + subtype : int + Filter subtype + dim_lag : int + Number of past time instances for smoother + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count number of past time steps for smoothing + flag : int + Status flag + + Returns + ------- + dim_obs_f : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (dim_ens, dim_ens) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count number of past time steps for smoothing + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_np = np.asarray(ainv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=3, mode="fortran", negative_indices=False, cast=False] sens_p_np = np.asarray(sens_p, dtype=np.float64, order="F") + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int dim_obs_f + with nogil: + c__pdafletkf_update(&step, &dim_p, &dim_obs_f, &dim_ens, + &state_p[0], &ainv[0,0], &ens_p[0,0], + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, &screen, &subtype, + &dim_lag, &sens_p[0,0,0], &cnt_maxlag, &flag) + + return dim_obs_f, state_p_np, ainv_np, ens_p_np, sens_p_np, cnt_maxlag, flag + + +def lseik_ana_trans(int domain_p, int step, int dim_l, int dim_obs_l, + int dim_ens, int rank, double [::1] state_l, double [::1,:] uinv_l, + double [::1,:] ens_l, double [::1,:] hl_l, double [::1] hxbar_l, + double [::1] obs_l, double [::1,:] omegat_in, double forget, + py__prodrinva_l_pdaf, int nm1vsn, int type_sqrt, int screen, + int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + step : int + Current time step + dim_l : int + State dimension on local analysis domain + dim_obs_l : int + Size of obs. vector on local ana. domain + dim_ens : int + Size of ensemble + rank : int + Rank of initial covariance matrix + state_l : ndarray[np.float64, ndim=1] + on exit: state on local analysis domain + Array shape: (dim_l) + uinv_l : ndarray[np.float64, ndim=2] + Inverse of matrix U - temporary use only + Array shape: (rank, rank) + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + hl_l : ndarray[np.float64, ndim=2] + Local observed state ensemble (perturbation) + Array shape: (dim_obs_l, dim_ens) + hxbar_l : ndarray[np.float64, ndim=1] + Local observed ensemble mean + Array shape: (dim_obs_l) + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_l) + omegat_in : ndarray[np.float64, ndim=2] + Matrix Omega + Array shape: (rank, dim_ens) + forget : double + Forgetting factor + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A for local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + nm1vsn : int + Whether covariance is normalized with 1/N or 1/(N-1) + type_sqrt : int + Type of square-root of A + screen : int + Verbosity flag + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_l : ndarray[np.float64, ndim=1] + on exit: state on local analysis domain + Array shape: (dim_l) + uinv_l : ndarray[np.float64, ndim=2] + Inverse of matrix U - temporary use only + Array shape: (rank, rank) + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + hl_l : ndarray[np.float64, ndim=2] + Local observed state ensemble (perturbation) + Array shape: (dim_obs_l, dim_ens) + omegat_in : ndarray[np.float64, ndim=2] + Matrix Omega + Array shape: (rank, dim_ens) + forget : double + Forgetting factor + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_l_np = np.asarray(state_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] uinv_l_np = np.asarray(uinv_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_l_np = np.asarray(ens_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hl_l_np = np.asarray(hl_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] omegat_in_np = np.asarray(omegat_in, dtype=np.float64, order="F") + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + with nogil: + c__pdaf_lseik_ana_trans(&domain_p, &step, &dim_l, &dim_obs_l, + &dim_ens, &rank, &state_l[0], &uinv_l[0,0], + &ens_l[0,0], &hl_l[0,0], &hxbar_l[0], + &obs_l[0], &omegat_in[0,0], &forget, + pdaf_cb.c__prodrinva_l_pdaf, &nm1vsn, + &type_sqrt, &screen, &debug, &flag) + + return state_l_np, uinv_l_np, ens_l_np, hl_l_np, omegat_in_np, forget, flag + + +def en3dvar_optim_lbfgs(int step, int dim_p, int dim_ens, + int dim_cvec_p, int dim_obs_p, double [::1,:] ens_p, + double [::1] obs_p, double [::1] dy_p, double [::1] v_p, + py__prodrinva_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, int opt_parallel, int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local state dimension + dim_ens : int + ensemble size + dim_cvec_p : int + Size of control vector + dim_obs_p : int + PE-local dimension of observation vector + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + dy_p : ndarray[np.float64, ndim=1] + Background innovation + Array shape: (dim_obs_p) + v_p : ndarray[np.float64, ndim=1] + Control vector + Array shape: (dim_cvec_p) + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + opt_parallel : int + Whether to use a decomposed control vector + screen : int + Verbosity flag + + Returns + ------- + v_p : ndarray[np.float64, ndim=1] + Control vector + Array shape: (dim_cvec_p) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] v_p_np = np.asarray(v_p, dtype=np.float64, order="F") + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + with nogil: + c__pdaf_en3dvar_optim_lbfgs(&step, &dim_p, &dim_ens, &dim_cvec_p, + &dim_obs_p, &ens_p[0,0], &obs_p[0], + &dy_p[0], &v_p[0], + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + &opt_parallel, &screen) + + return v_p_np + + +def en3dvar_optim_cgplus(int step, int dim_p, int dim_ens, + int dim_cvec_p, int dim_obs_p, double [::1,:] ens_p, + double [::1] obs_p, double [::1] dy_p, double [::1] v_p, + py__prodrinva_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, int opt_parallel, int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local state dimension + dim_ens : int + ensemble size + dim_cvec_p : int + Size of control vector + dim_obs_p : int + PE-local dimension of observation vector + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + dy_p : ndarray[np.float64, ndim=1] + Background innovation + Array shape: (dim_obs_p) + v_p : ndarray[np.float64, ndim=1] + Control vector + Array shape: (dim_cvec_p) + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + opt_parallel : int + Whether to use a decomposed control vector + screen : int + Verbosity flag + + Returns + ------- + v_p : ndarray[np.float64, ndim=1] + Control vector + Array shape: (dim_cvec_p) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] v_p_np = np.asarray(v_p, dtype=np.float64, order="F") + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + with nogil: + c__pdaf_en3dvar_optim_cgplus(&step, &dim_p, &dim_ens, &dim_cvec_p, + &dim_obs_p, &ens_p[0,0], &obs_p[0], + &dy_p[0], &v_p[0], + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + &opt_parallel, &screen) + + return v_p_np + + +def en3dvar_optim_cg(int step, int dim_p, int dim_ens, int dim_cvec_p, + int dim_obs_p, double [::1,:] ens_p, double [::1] obs_p, + double [::1] dy_p, double [::1] v_p, py__prodrinva_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, int opt_parallel, int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local state dimension + dim_ens : int + ensemble size + dim_cvec_p : int + Size of control vector + dim_obs_p : int + PE-local dimension of observation vector + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + dy_p : ndarray[np.float64, ndim=1] + Background innovation + Array shape: (dim_obs_p) + v_p : ndarray[np.float64, ndim=1] + Control vector + Array shape: (dim_cvec_p) + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + opt_parallel : int + Whether to use a decomposed control vector + screen : int + Verbosity flag + + Returns + ------- + v_p : ndarray[np.float64, ndim=1] + Control vector + Array shape: (dim_cvec_p) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] v_p_np = np.asarray(v_p, dtype=np.float64, order="F") + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + with nogil: + c__pdaf_en3dvar_optim_cg(&step, &dim_p, &dim_ens, &dim_cvec_p, + &dim_obs_p, &ens_p[0,0], &obs_p[0], + &dy_p[0], &v_p[0], + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, &opt_parallel, + &screen) + + return v_p_np + + +def en3dvar_costf_cvt(int step, int iter, int dim_p, int dim_ens, + int dim_cvec_p, int dim_obs_p, double [::1,:] ens_p, + double [::1] obs_p, double [::1] dy_p, double [::1] v_p, + py__prodrinva_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, int opt_parallel): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + iter : int + Optimization iteration + dim_p : int + PE-local state dimension + dim_ens : int + ensemble size + dim_cvec_p : int + PE-local size of control vector + dim_obs_p : int + PE-local dimension of observation vector + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + dy_p : ndarray[np.float64, ndim=1] + background innovation + Array shape: (dim_obs_p) + v_p : ndarray[np.float64, ndim=1] + control vector + Array shape: (dim_cvec_p) + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + opt_parallel : int + Whether to use a decomposed control vector + + Returns + ------- + j_tot : double + on exit: Value of cost function + gradj : ndarray[np.float64, ndim=1] + on exit: PE-local gradient of J + Array shape: (dim_cvec_p) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] gradj_np = np.zeros((dim_cvec_p), dtype=np.float64, order="F") + cdef double [::1] gradj = gradj_np + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + cdef double j_tot + with nogil: + c__pdaf_en3dvar_costf_cvt(&step, &iter, &dim_p, &dim_ens, + &dim_cvec_p, &dim_obs_p, &ens_p[0,0], + &obs_p[0], &dy_p[0], &v_p[0], &j_tot, + &gradj[0], pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, &opt_parallel) + + return j_tot, gradj_np + + +def en3dvar_costf_cg_cvt(int step, int iter, int dim_p, int dim_ens, + int dim_cvec_p, int dim_obs_p, double [::1,:] ens_p, + double [::1] obs_p, double [::1] dy_p, double [::1] v_p, + double [::1] d_p, py__prodrinva_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, + int opt_parallel): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + iter : int + Optimization iteration + dim_p : int + PE-local state dimension + dim_ens : int + ensemble size + dim_cvec_p : int + PE-local size of control vector + dim_obs_p : int + PE-local dimension of observation vector + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + dy_p : ndarray[np.float64, ndim=1] + Background innovation + Array shape: (dim_obs_p) + v_p : ndarray[np.float64, ndim=1] + Control vector + Array shape: (dim_cvec_p) + d_p : ndarray[np.float64, ndim=1] + CG descent direction + Array shape: (dim_cvec_p) + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + opt_parallel : int + Whether to use a decomposed control vector + + Returns + ------- + d_p : ndarray[np.float64, ndim=1] + CG descent direction + Array shape: (dim_cvec_p) + j_tot : double + on exit: Value of cost function + gradj : ndarray[np.float64, ndim=1] + on exit: gradient of J + Array shape: (dim_cvec_p) + hessjd : ndarray[np.float64, ndim=1] + on exit: Hessian of J times d_p + Array shape: (dim_cvec_p) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] d_p_np = np.asarray(d_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] gradj_np = np.zeros((dim_cvec_p), dtype=np.float64, order="F") + cdef double [::1] gradj = gradj_np + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] hessjd_np = np.zeros((dim_cvec_p), dtype=np.float64, order="F") + cdef double [::1] hessjd = hessjd_np + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + cdef double j_tot + with nogil: + c__pdaf_en3dvar_costf_cg_cvt(&step, &iter, &dim_p, &dim_ens, + &dim_cvec_p, &dim_obs_p, &ens_p[0,0], + &obs_p[0], &dy_p[0], &v_p[0], &d_p[0], + &j_tot, &gradj[0], &hessjd[0], + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, &opt_parallel) + + return d_p_np, j_tot, gradj_np, hessjd_np + + +def gather_ens(int dim_p, int dim_ens_p, double [::1,:] ens, + double [::1] state, int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_p : int + PE-local dimension of model state + dim_ens_p : int + Size of ensemble + ens : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (:, :) + screen : int + Verbosity flag + + Returns + ------- + ens : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (:, :) + """ + cdef CFI_cdesc_rank2 ens_cfi + cdef CFI_cdesc_t *ens_ptr = &ens_cfi + cdef size_t ens_nbytes = ens.nbytes + cdef CFI_index_t ens_extent[2] + ens_extent[0] = ens.shape[0] + ens_extent[1] = ens.shape[1] + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_np = np.asarray(ens, dtype=np.float64, order="F") + + cdef CFI_cdesc_rank1 state_cfi + cdef CFI_cdesc_t *state_ptr = &state_cfi + cdef size_t state_nbytes = state.nbytes + cdef CFI_index_t state_extent[1] + state_extent[0] = state.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_np = np.asarray(state, dtype=np.float64, order="F") + + with nogil: + CFI_establish(ens_ptr, &ens[0,0], CFI_attribute_other, + CFI_type_double , ens_nbytes, 2, ens_extent) + + CFI_establish(state_ptr, &state[0], CFI_attribute_other, + CFI_type_double , state_nbytes, 1, state_extent) + + c__pdaf_gather_ens(&dim_p, &dim_ens_p, ens_ptr, state_ptr, &screen) + + return ens_np, state_np + + +def scatter_ens(int dim_p, int dim_ens_p, double [::1,:] ens, + double [::1] state, int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_p : int + PE-local dimension of model state + dim_ens_p : int + Size of ensemble + ens : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (:, :) + state : ndarray[np.float64, ndim=1] + PE-local state vector (for SEEK) + Array shape: (:) + screen : int + Verbosity flag + + Returns + ------- + ens : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (:, :) + state : ndarray[np.float64, ndim=1] + PE-local state vector (for SEEK) + Array shape: (:) + """ + cdef CFI_cdesc_rank2 ens_cfi + cdef CFI_cdesc_t *ens_ptr = &ens_cfi + cdef size_t ens_nbytes = ens.nbytes + cdef CFI_index_t ens_extent[2] + ens_extent[0] = ens.shape[0] + ens_extent[1] = ens.shape[1] + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_np = np.asarray(ens, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 state_cfi + cdef CFI_cdesc_t *state_ptr = &state_cfi + cdef size_t state_nbytes = state.nbytes + cdef CFI_index_t state_extent[1] + state_extent[0] = state.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_np = np.asarray(state, dtype=np.float64, order="F") + with nogil: + CFI_establish(ens_ptr, &ens[0,0], CFI_attribute_other, + CFI_type_double , ens_nbytes, 2, ens_extent) + + CFI_establish(state_ptr, &state[0], CFI_attribute_other, + CFI_type_double , state_nbytes, 1, state_extent) + + c__pdaf_scatter_ens(&dim_p, &dim_ens_p, ens_ptr, state_ptr, &screen) + + return ens_np, state_np + + +def hyb3dvar_optim_lbfgs(int step, int dim_p, int dim_ens, + int dim_cv_par_p, int dim_cv_ens_p, int dim_obs_p, + double [::1,:] ens_p, double [::1] obs_p, double [::1] dy_p, + double [::1] v_par_p, double [::1] v_ens_p, py__prodrinva_pdaf, + py__cvt_pdaf, py__cvt_adj_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, int opt_parallel, + double beta_3dvar, int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local state dimension + dim_ens : int + ensemble size + dim_cv_par_p : int + Size of control vector (parameterized) + dim_cv_ens_p : int + Size of control vector (ensemble) + dim_obs_p : int + PE-local dimension of observation vector + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + dy_p : ndarray[np.float64, ndim=1] + Background innovation + Array shape: (dim_obs_p) + v_par_p : ndarray[np.float64, ndim=1] + Control vector (parameterized part) + Array shape: (dim_cv_par_p) + v_ens_p : ndarray[np.float64, ndim=1] + Control vector (ensemble part) + Array shape: (dim_cv_ens_p) + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector (parameterized) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix (parameterized) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + opt_parallel : int + Whether to use a decomposed control vector + beta_3dvar : double + Hybrid weight + screen : int + Verbosity flag + + Returns + ------- + v_par_p : ndarray[np.float64, ndim=1] + Control vector (parameterized part) + Array shape: (dim_cv_par_p) + v_ens_p : ndarray[np.float64, ndim=1] + Control vector (ensemble part) + Array shape: (dim_cv_ens_p) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] v_par_p_np = np.asarray(v_par_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] v_ens_p_np = np.asarray(v_ens_p, dtype=np.float64, order="F") + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + with nogil: + c__pdaf_hyb3dvar_optim_lbfgs(&step, &dim_p, &dim_ens, + &dim_cv_par_p, &dim_cv_ens_p, + &dim_obs_p, &ens_p[0,0], &obs_p[0], + &dy_p[0], &v_par_p[0], &v_ens_p[0], + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + &opt_parallel, &beta_3dvar, &screen) + + return v_par_p_np, v_ens_p_np + + +def hyb3dvar_optim_cgplus(int step, int dim_p, int dim_ens, + int dim_cv_par_p, int dim_cv_ens_p, int dim_obs_p, + double [::1,:] ens_p, double [::1] obs_p, double [::1] dy_p, + double [::1] v_par_p, double [::1] v_ens_p, py__prodrinva_pdaf, + py__cvt_pdaf, py__cvt_adj_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, int opt_parallel, + double beta_3dvar, int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local state dimension + dim_ens : int + ensemble size + dim_cv_par_p : int + Size of control vector (parameterized) + dim_cv_ens_p : int + Size of control vector (ensemble) + dim_obs_p : int + PE-local dimension of observation vector + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + dy_p : ndarray[np.float64, ndim=1] + Background innovation + Array shape: (dim_obs_p) + v_par_p : ndarray[np.float64, ndim=1] + Control vector (parameterized part) + Array shape: (dim_cv_par_p) + v_ens_p : ndarray[np.float64, ndim=1] + Control vector (ensemble part) + Array shape: (dim_cv_ens_p) + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector (parameterized) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix (parameterized) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + opt_parallel : int + Whether to use a decomposed control vector + beta_3dvar : double + Hybrid weight + screen : int + Verbosity flag + + Returns + ------- + v_par_p : ndarray[np.float64, ndim=1] + Control vector (parameterized part) + Array shape: (dim_cv_par_p) + v_ens_p : ndarray[np.float64, ndim=1] + Control vector (ensemble part) + Array shape: (dim_cv_ens_p) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] v_par_p_np = np.asarray(v_par_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] v_ens_p_np = np.asarray(v_ens_p, dtype=np.float64, order="F") + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + with nogil: + c__pdaf_hyb3dvar_optim_cgplus(&step, &dim_p, &dim_ens, + &dim_cv_par_p, &dim_cv_ens_p, + &dim_obs_p, &ens_p[0,0], &obs_p[0], + &dy_p[0], &v_par_p[0], &v_ens_p[0], + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + &opt_parallel, &beta_3dvar, &screen) + + return v_par_p_np, v_ens_p_np + + +def hyb3dvar_optim_cg(int step, int dim_p, int dim_ens, + int dim_cv_par_p, int dim_cv_ens_p, int dim_obs_p, + double [::1,:] ens_p, double [::1] obs_p, double [::1] dy_p, + double [::1] v_par_p, double [::1] v_ens_p, py__prodrinva_pdaf, + py__cvt_pdaf, py__cvt_adj_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, int opt_parallel, + double beta_3dvar, int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local state dimension + dim_ens : int + ensemble size + dim_cv_par_p : int + Size of control vector (parameterized) + dim_cv_ens_p : int + Size of control vector (ensemble) + dim_obs_p : int + PE-local dimension of observation vector + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + dy_p : ndarray[np.float64, ndim=1] + Background innovation + Array shape: (dim_obs_p) + v_par_p : ndarray[np.float64, ndim=1] + Control vector (parameterized part) + Array shape: (dim_cv_par_p) + v_ens_p : ndarray[np.float64, ndim=1] + Control vector (ensemble part) + Array shape: (dim_cv_ens_p) + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector (parameterized) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix (parameterized) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + opt_parallel : int + Whether to use a decomposed control vector + beta_3dvar : double + Hybrid weight + screen : int + Verbosity flag + + Returns + ------- + v_par_p : ndarray[np.float64, ndim=1] + Control vector (parameterized part) + Array shape: (dim_cv_par_p) + v_ens_p : ndarray[np.float64, ndim=1] + Control vector (ensemble part) + Array shape: (dim_cv_ens_p) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] v_par_p_np = np.asarray(v_par_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] v_ens_p_np = np.asarray(v_ens_p, dtype=np.float64, order="F") + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + with nogil: + c__pdaf_hyb3dvar_optim_cg(&step, &dim_p, &dim_ens, &dim_cv_par_p, + &dim_cv_ens_p, &dim_obs_p, &ens_p[0,0], + &obs_p[0], &dy_p[0], &v_par_p[0], + &v_ens_p[0], pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + &opt_parallel, &beta_3dvar, &screen) + + return v_par_p_np, v_ens_p_np + + +def hyb3dvar_costf_cvt(int step, int iter, int dim_p, int dim_ens, + int dim_cv_p, int dim_cv_par_p, int dim_cv_ens_p, int dim_obs_p, + double [::1,:] ens_p, double [::1] obs_p, double [::1] dy_p, + double [::1] v_par_p, double [::1] v_ens_p, double [::1] v_p, + py__prodrinva_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, + int opt_parallel, double beta): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + iter : int + Optimization iteration + dim_p : int + PE-local state dimension + dim_ens : int + ensemble size + dim_cv_p : int + Size of control vector (full) + dim_cv_par_p : int + Size of control vector (parameterized part) + dim_cv_ens_p : int + Size of control vector (ensemble part) + dim_obs_p : int + PE-local dimension of observation vector + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + dy_p : ndarray[np.float64, ndim=1] + background innovation + Array shape: (dim_obs_p) + v_par_p : ndarray[np.float64, ndim=1] + Control vector (parameterized part) + Array shape: (dim_cv_par_p) + v_ens_p : ndarray[np.float64, ndim=1] + Control vector (ensemble part) + Array shape: (dim_cv_ens_p) + v_p : ndarray[np.float64, ndim=1] + Control vector (full) + Array shape: (dim_cv_p) + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector (parameterized) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix (parameterized) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + opt_parallel : int + Whether to use a decomposed control vector + beta : double + Hybrid weight + + Returns + ------- + v_par_p : ndarray[np.float64, ndim=1] + Control vector (parameterized part) + Array shape: (dim_cv_par_p) + v_ens_p : ndarray[np.float64, ndim=1] + Control vector (ensemble part) + Array shape: (dim_cv_ens_p) + j_tot : double + on exit: Value of cost function + gradj : ndarray[np.float64, ndim=1] + on exit: PE-local gradient of J (full) + Array shape: (dim_cv_p) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] v_par_p_np = np.asarray(v_par_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] v_ens_p_np = np.asarray(v_ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] gradj_np = np.zeros((dim_cv_p), dtype=np.float64, order="F") + cdef double [::1] gradj = gradj_np + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + cdef double j_tot + with nogil: + c__pdaf_hyb3dvar_costf_cvt(&step, &iter, &dim_p, &dim_ens, + &dim_cv_p, &dim_cv_par_p, &dim_cv_ens_p, + &dim_obs_p, &ens_p[0,0], &obs_p[0], + &dy_p[0], &v_par_p[0], &v_ens_p[0], + &v_p[0], &j_tot, &gradj[0], + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + &opt_parallel, &beta) + + return v_par_p_np, v_ens_p_np, j_tot, gradj_np + + +def hyb3dvar_costf_cg_cvt(int step, int iter, int dim_p, int dim_ens, + int dim_cv_par_p, int dim_cv_ens_p, int dim_obs_p, + double [::1,:] ens_p, double [::1] obs_p, double [::1] dy_p, + double [::1] v_par_p, double [::1] v_ens_p, double [::1] d_par_p, + double [::1] d_ens_p, py__prodrinva_pdaf, py__cvt_pdaf, + py__cvt_adj_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, int opt_parallel, double beta): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + iter : int + Optimization iteration + dim_p : int + PE-local state dimension + dim_ens : int + ensemble size + dim_cv_par_p : int + Size of control vector (parameterized part) + dim_cv_ens_p : int + Size of control vector (ensemble part) + dim_obs_p : int + PE-local dimension of observation vector + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + dy_p : ndarray[np.float64, ndim=1] + Background innovation + Array shape: (dim_obs_p) + v_par_p : ndarray[np.float64, ndim=1] + Control vector (parameterized part) + Array shape: (dim_cv_par_p) + v_ens_p : ndarray[np.float64, ndim=1] + Control vector (ensemble part) + Array shape: (dim_cv_ens_p) + d_par_p : ndarray[np.float64, ndim=1] + CG descent direction (parameterized part) + Array shape: (dim_cv_par_p) + d_ens_p : ndarray[np.float64, ndim=1] + CG descent direction (ensemble part) + Array shape: (dim_cv_ens_p) + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector (parameterized) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix (parameterized) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + opt_parallel : int + Whether to use a decomposed control vector + beta : double + Hybrid weight + + Returns + ------- + d_par_p : ndarray[np.float64, ndim=1] + CG descent direction (parameterized part) + Array shape: (dim_cv_par_p) + d_ens_p : ndarray[np.float64, ndim=1] + CG descent direction (ensemble part) + Array shape: (dim_cv_ens_p) + j_tot : double + on exit: Value of cost function + gradj_par : ndarray[np.float64, ndim=1] + on exit: gradient of J (parameterized part) + Array shape: (dim_cv_par_p) + gradj_ens : ndarray[np.float64, ndim=1] + on exit: gradient of J (ensemble part) + Array shape: (dim_cv_ens_p) + hessjd_par : ndarray[np.float64, ndim=1] + on exit: Hessian of J times d_p (parameterized part) + Array shape: (dim_cv_par_p) + hessjd_ens : ndarray[np.float64, ndim=1] + on exit: Hessian of J times d_p (ensemble part) + Array shape: (dim_cv_ens_p) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] d_par_p_np = np.asarray(d_par_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] d_ens_p_np = np.asarray(d_ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] gradj_par_np = np.zeros((dim_cv_par_p), dtype=np.float64, order="F") + cdef double [::1] gradj_par = gradj_par_np + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] gradj_ens_np = np.zeros((dim_cv_ens_p), dtype=np.float64, order="F") + cdef double [::1] gradj_ens = gradj_ens_np + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] hessjd_par_np = np.zeros((dim_cv_par_p), dtype=np.float64, order="F") + cdef double [::1] hessjd_par = hessjd_par_np + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] hessjd_ens_np = np.zeros((dim_cv_ens_p), dtype=np.float64, order="F") + cdef double [::1] hessjd_ens = hessjd_ens_np + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + cdef double j_tot + with nogil: + c__pdaf_hyb3dvar_costf_cg_cvt(&step, &iter, &dim_p, &dim_ens, + &dim_cv_par_p, &dim_cv_ens_p, + &dim_obs_p, &ens_p[0,0], &obs_p[0], + &dy_p[0], &v_par_p[0], &v_ens_p[0], + &d_par_p[0], &d_ens_p[0], &j_tot, + &gradj_par[0], &gradj_ens[0], + &hessjd_par[0], &hessjd_ens[0], + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + &opt_parallel, &beta) + + return d_par_p_np, d_ens_p_np, j_tot, gradj_par_np, gradj_ens_np, hessjd_par_np, hessjd_ens_np + + +def print_version(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdaf_print_version() + + + +def en3dvar_analysis_cvt(int step, int dim_p, int dim_obs_p, + int dim_ens, int dim_cvec_ens, double [::1,:] ens_p, + double [::1] state_inc_p, double [::1] hxbar_p, double [::1] obs_p, + py__prodrinva_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, int screen, int type_opt, + int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_obs_p : int + PE-local dimension of observation vector + dim_ens : int + Size of ensemble + dim_cvec_ens : int + Size of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + state_inc_p : ndarray[np.float64, ndim=1] + PE-local state analysis increment + Array shape: (dim_p) + hxbar_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + screen : int + Verbosity flag + type_opt : int + Type of minimizer for 3DVar + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + on exit: PE-local forecast state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + state_inc_p : ndarray[np.float64, ndim=1] + PE-local state analysis increment + Array shape: (dim_p) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.zeros((dim_p), dtype=np.float64, order="F") + cdef double [::1] state_p = state_p_np + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_inc_p_np = np.asarray(state_inc_p, dtype=np.float64, order="F") + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + with nogil: + c__pdafen3dvar_analysis_cvt(&step, &dim_p, &dim_obs_p, &dim_ens, + &dim_cvec_ens, &state_p[0], + &ens_p[0,0], &state_inc_p[0], + &hxbar_p[0], &obs_p[0], + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, &screen, + &type_opt, &debug, &flag) + + return state_p_np, ens_p_np, state_inc_p_np, flag + + +def sisort(int n, double [::1] veca): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + n : int + + veca : ndarray[np.float64, ndim=1] + + Array shape: (n) + + Returns + ------- + veca : ndarray[np.float64, ndim=1] + + Array shape: (n) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] veca_np = np.asarray(veca, dtype=np.float64, order="F") + with nogil: + c__pdaf_sisort(&n, &veca[0]) + + return veca_np + +def enkf_ana_rlm(int step, int dim_p, int dim_obs_p, int dim_obs, int dim_ens, + int rank_ana, double [::1] state_p, double [::1,:] ens_p, + double [::1,:] hzb, double [::1,:] hx_p, double [::1] hxbar_p, + double [::1] obs_p, py__add_obs_err_pdaf, py__init_obs_covar_pdaf, + int screen, int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_obs_p : int + PE-local dimension of observation vector + dim_obs : int + Global dimension of observation vector + dim_ens : int + Size of state ensemble + rank_ana : int + Rank to be considered for inversion of HPH + state_p : ndarray[np.float64, ndim=1] + PE-local ensemble mean state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hzb : ndarray[np.float64, ndim=2] + Ensemble tranformation matrix + Array shape: (dim_ens, dim_ens) + hx_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble + Array shape: (dim_obs_p, dim_ens) + hxbar_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + py__add_obs_err_pdaf : Callable + Add observation error covariance matrix + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Dimension of observation vector + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + py__init_obs_covar_pdaf : Callable + Initialize observation error covariance matrix + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs : int + Global size of observation vector + dim_obs_p : int + Size of process-local observation vector + obs_p : ndarray[np.float64, ndim=1] + Process-local vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + covar : ndarray[np.float64, ndim=2] + Observation error covariance matrix + Array shape: (dim_obs_p,dim_obs_p) + isdiag : bint + + + screen : int + Verbosity flag + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + PE-local ensemble mean state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hzb : ndarray[np.float64, ndim=2] + Ensemble tranformation matrix + Array shape: (dim_ens, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hzb_np = np.asarray(hzb, dtype=np.float64, order="F") + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + with nogil: + c__pdaf_enkf_ana_rlm(&step, &dim_p, &dim_obs_p, &dim_obs, &dim_ens, + &rank_ana, &state_p[0], &ens_p[0,0], + &hzb[0,0], &hx_p[0,0], &hxbar_p[0], &obs_p[0], + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, &screen, + &debug, &flag) + + return state_p_np, ens_p_np, hzb_np, flag + + +def smoother_enkf(int dim_p, int dim_ens, int dim_lag, + double [::1,:] ainv, double [::1,:,:] sens_p, int cnt_maxlag, + double forget, int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + dim_lag : int + Number of past time instances for smoother + ainv : ndarray[np.float64, ndim=2] + Weight matrix for ensemble transformation + Array shape: (dim_ens, dim_ens) + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count available number of time steps for smoothing + forget : double + Forgetting factor + screen : int + Verbosity flag + + Returns + ------- + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count available number of time steps for smoothing + """ + cdef cnp.ndarray[cnp.float64_t, ndim=3, mode="fortran", negative_indices=False, cast=False] sens_p_np = np.asarray(sens_p, dtype=np.float64, order="F") + with nogil: + c__pdaf_smoother_enkf(&dim_p, &dim_ens, &dim_lag, &ainv[0,0], + &sens_p[0,0,0], &cnt_maxlag, &forget, &screen) + + return sens_p_np, cnt_maxlag + + +def ensrf_update(int step, int dim_p, int dim_ens, + double [::1] state_p, double [::1,:] ens_p, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__init_obsvar_pdaf, + py__localize_covar_serial_pdaf, py__prepoststep_pdaf, int screen, + int subtype, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of state ensemble + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obsvar_pdaf : Callable + Initialize vector of observation error variances + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__localize_covar_serial_pdaf : Callable + Apply localization for single-observation vectors + + Callback Parameters + ------------------- + iobs : int + Index of current observation + dim_p : int + Process-local state dimension + dim_obs : int + Number of observations + hp_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HP for observation iobs + Array shape: (dim_p) + hxy_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HX(HX_all) for full observations + Array shape: (dim_obs) + + Callback Returns + ---------------- + hp_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HP for observation iobs + Array shape: (dim_p) + hxy_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HX(HX_all) for full observations + Array shape: (dim_obs) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + screen : int + Verbosity flag + subtype : int + Specification of filter subtype + flag : int + Status flag + + Returns + ------- + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.localize_covar_serial_pdaf = py__localize_covar_serial_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int dim_obs_p + with nogil: + c__pdafensrf_update(&step, &dim_p, &dim_obs_p, &dim_ens, + &state_p[0], &ens_p[0,0], + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__localize_covar_serial_pdaf, + pdaf_cb.c__prepoststep_pdaf, &screen, &subtype, + &flag) + + return dim_obs_p, state_p_np, ens_p_np, flag + + +def pf_ana(int step, int dim_p, int dim_obs_p, int dim_ens, + double [::1] state_p, double [::1,:] ens_p, int type_resample, + int type_winf, double limit_winf, int type_noise, double noise_amp, + double [::1,:] hz_p, double [::1] obs_p, py__likelihood_pdaf, + int screen, int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_obs_p : int + PE-local dimension of observation vector + dim_ens : int + Size of ensemble + state_p : ndarray[np.float64, ndim=1] + PE-local forecast mean state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + type_resample : int + Type of resampling scheme + type_winf : int + Type of weights inflation + limit_winf : double + Limit for weights inflation + type_noise : int + Type of pertubing noise + noise_amp : double + Amplitude of noise + hz_p : ndarray[np.float64, ndim=2] + Temporary matrices for analysis + Array shape: (dim_obs_p, dim_ens) + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + py__likelihood_pdaf : Callable + Compute observation likelihood for an ensemble member + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + resid : ndarray[np.float64, ndim=1] + Input vector holding the residual + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + likely : double + Output value of the likelihood + + screen : int + Verbosity flag + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + PE-local forecast mean state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + pdaf_cb.likelihood_pdaf = py__likelihood_pdaf + with nogil: + c__pdaf_pf_ana(&step, &dim_p, &dim_obs_p, &dim_ens, &state_p[0], + &ens_p[0,0], &type_resample, &type_winf, + &limit_winf, &type_noise, &noise_amp, &hz_p[0,0], + &obs_p[0], pdaf_cb.c__likelihood_pdaf, &screen, + &debug, &flag) + + return state_p_np, ens_p_np, flag + + +def pf_resampling(int method, int nin, int nout, double [::1] weights, + int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + method : int + Choose resampling method + nin : int + number of particles + nout : int + number of particles to be resampled + weights : ndarray[np.float64, ndim=1] + Weights + Array shape: (nin) + screen : int + Verbosity flag + + Returns + ------- + ids : ndarray[np.intc, ndim=1] + Indices of resampled ensmeble states + Array shape: (nout) + """ + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] ids_np = np.zeros((nout), dtype=np.intc, order="F") + cdef int [::1] ids = ids_np + with nogil: + c__pdaf_pf_resampling(&method, &nin, &nout, &weights[0], &ids[0], + &screen) + + return ids_np + + +def mvnormalize(int mode, int dim_state, int dim_field, int offset, + int ncol, double [::1,:] states, double stddev): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + mode : int + Mode: (1) normalize, (2) re-scale + dim_state : int + Dimension of state vector + dim_field : int + Dimension of a field in state vector + offset : int + Offset of field in state vector + ncol : int + Number of columns in array states + states : ndarray[np.float64, ndim=2] + State vector array + Array shape: (dim_state, ncol) + stddev : double + Standard deviation of field + + Returns + ------- + states : ndarray[np.float64, ndim=2] + State vector array + Array shape: (dim_state, ncol) + stddev : double + Standard deviation of field + status : int + Status flag (0=success) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] states_np = np.asarray(states, dtype=np.float64, order="F") + cdef int status + with nogil: + c__pdaf_mvnormalize(&mode, &dim_state, &dim_field, &offset, &ncol, + &states[0,0], &stddev, &status) + + return states_np, stddev, status + + +def _3dvar_init(int subtype, int [::1] param_int, int dim_pint, + double [::1] param_real, int dim_preal, int verbose, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + dim_pint : int + Number of integer parameters + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + dim_preal : int + Number of real parameters + verbose : int + Control screen output + outflag : int + Status flag + + Returns + ------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + ensemblefilter : bint + Is the chosen filter ensemble-based? + fixedbasis : bint + Does the filter run with fixed error-space basis? + outflag : int + Status flag + """ + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_int_np = np.asarray(param_int, dtype=np.intc, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_real_np = np.asarray(param_real, dtype=np.float64, order="F") + cdef bint ensemblefilter + cdef bint fixedbasis + with nogil: + c__pdaf_3dvar_init(&subtype, ¶m_int[0], &dim_pint, + ¶m_real[0], &dim_preal, &ensemblefilter, + &fixedbasis, &verbose, &outflag) + + return subtype, param_int_np, param_real_np, ensemblefilter, fixedbasis, outflag + + +def _3dvar_alloc(int subtype, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + with nogil: + c__pdaf_3dvar_alloc(&subtype, &outflag) + + return outflag + + +def _3dvar_config(int subtype, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + verbose : int + Control screen output + + Returns + ------- + subtype : int + Sub-type of filter + """ + with nogil: + c__pdaf_3dvar_config(&subtype, &verbose) + + return subtype + + +def _3dvar_set_iparam(int id, int value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : int + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_3dvar_set_iparam(&id, &value, &flag) + + return flag + + +def _3dvar_set_rparam(int id, double value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : double + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_3dvar_set_rparam(&id, &value, &flag) + + return flag + + +def _3dvar_options(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdaf_3dvar_options() + + + +def _3dvar_memtime(int printtype): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + printtype : int + Type of screen output: + + Returns + ------- + """ + with nogil: + c__pdaf_3dvar_memtime(&printtype) + + + +def reset_dim_ens(int dim_ens_in, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_ens_in : int + Sub-type of filter + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + with nogil: + c__pdaf_reset_dim_ens(&dim_ens_in, &outflag) + + return outflag + + +def reset_dim_p(int dim_p_in, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_p_in : int + Sub-type of filter + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + with nogil: + c__pdaf_reset_dim_p(&dim_p_in, &outflag) + + return outflag + + +def _3dvar_optim_lbfgs(int step, int dim_p, int dim_cvec_p, + int dim_obs_p, double [::1] obs_p, double [::1] dy_p, + double [::1] v_p, py__prodrinva_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, int opt_parallel, int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local state dimension + dim_cvec_p : int + Size of control vector + dim_obs_p : int + PE-local dimension of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + dy_p : ndarray[np.float64, ndim=1] + Background innovation + Array shape: (dim_obs_p) + v_p : ndarray[np.float64, ndim=1] + Control vector + Array shape: (dim_cvec_p) + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + opt_parallel : int + Whether to use a decomposed control vector + screen : int + Verbosity flag + + Returns + ------- + v_p : ndarray[np.float64, ndim=1] + Control vector + Array shape: (dim_cvec_p) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] v_p_np = np.asarray(v_p, dtype=np.float64, order="F") + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + with nogil: + c__pdaf_3dvar_optim_lbfgs(&step, &dim_p, &dim_cvec_p, &dim_obs_p, + &obs_p[0], &dy_p[0], &v_p[0], + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + &opt_parallel, &screen) + + return v_p_np + + +def _3dvar_optim_cgplus(int step, int dim_p, int dim_cvec_p, + int dim_obs_p, double [::1] obs_p, double [::1] dy_p, + double [::1] v_p, py__prodrinva_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, int opt_parallel, int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local state dimension + dim_cvec_p : int + Size of control vector + dim_obs_p : int + PE-local dimension of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + dy_p : ndarray[np.float64, ndim=1] + Background innovation + Array shape: (dim_obs_p) + v_p : ndarray[np.float64, ndim=1] + Control vector + Array shape: (dim_cvec_p) + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + opt_parallel : int + Whether to use a decomposed control vector + screen : int + Verbosity flag + + Returns + ------- + v_p : ndarray[np.float64, ndim=1] + Control vector + Array shape: (dim_cvec_p) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] v_p_np = np.asarray(v_p, dtype=np.float64, order="F") + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + with nogil: + c__pdaf_3dvar_optim_cgplus(&step, &dim_p, &dim_cvec_p, &dim_obs_p, + &obs_p[0], &dy_p[0], &v_p[0], + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + &opt_parallel, &screen) + + return v_p_np + + +def _3dvar_optim_cg(int step, int dim_p, int dim_cvec_p, int dim_obs_p, + double [::1] obs_p, double [::1] dy_p, double [::1] v_p, + py__prodrinva_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, int opt_parallel, int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local state dimension + dim_cvec_p : int + Size of control vector + dim_obs_p : int + PE-local dimension of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + dy_p : ndarray[np.float64, ndim=1] + Background innovation + Array shape: (dim_obs_p) + v_p : ndarray[np.float64, ndim=1] + Control vector + Array shape: (dim_cvec_p) + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + opt_parallel : int + Whether to use a decomposed control vector + screen : int + Verbosity flag + + Returns + ------- + v_p : ndarray[np.float64, ndim=1] + Control vector + Array shape: (dim_cvec_p) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] v_p_np = np.asarray(v_p, dtype=np.float64, order="F") + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + with nogil: + c__pdaf_3dvar_optim_cg(&step, &dim_p, &dim_cvec_p, &dim_obs_p, + &obs_p[0], &dy_p[0], &v_p[0], + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, &opt_parallel, + &screen) + + return v_p_np + + +def _3dvar_costf_cvt(int step, int iter, int dim_p, int dim_cvec_p, + int dim_obs_p, double [::1] obs_p, double [::1] dy_p, + double [::1] v_p, py__prodrinva_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, int opt_parallel): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + iter : int + Optimization iteration + dim_p : int + PE-local state dimension + dim_cvec_p : int + PE-local size of control vector + dim_obs_p : int + PE-local dimension of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + dy_p : ndarray[np.float64, ndim=1] + background innovation + Array shape: (dim_obs_p) + v_p : ndarray[np.float64, ndim=1] + control vector + Array shape: (dim_cvec_p) + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + opt_parallel : int + Whether to use a decomposed control vector + + Returns + ------- + j_tot : double + on exit: Value of cost function + gradj : ndarray[np.float64, ndim=1] + on exit: PE-local gradient of J + Array shape: (dim_cvec_p) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] gradj_np = np.zeros((dim_cvec_p), dtype=np.float64, order="F") + cdef double [::1] gradj = gradj_np + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + cdef double j_tot + with nogil: + c__pdaf_3dvar_costf_cvt(&step, &iter, &dim_p, &dim_cvec_p, + &dim_obs_p, &obs_p[0], &dy_p[0], &v_p[0], + &j_tot, &gradj[0], + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, &opt_parallel) + + return j_tot, gradj_np + + +def _3dvar_costf_cg_cvt(int step, int iter, int dim_p, int dim_cvec_p, + int dim_obs_p, double [::1] obs_p, double [::1] dy_p, + double [::1] v_p, double [::1] d_p, py__prodrinva_pdaf, py__cvt_pdaf, + py__cvt_adj_pdaf, py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, + int opt_parallel): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + iter : int + CG iteration + dim_p : int + PE-local state dimension + dim_cvec_p : int + PE-local size of control vector + dim_obs_p : int + PE-local dimension of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + dy_p : ndarray[np.float64, ndim=1] + Background innovation + Array shape: (dim_obs_p) + v_p : ndarray[np.float64, ndim=1] + Control vector + Array shape: (dim_cvec_p) + d_p : ndarray[np.float64, ndim=1] + CG descent direction + Array shape: (dim_cvec_p) + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + opt_parallel : int + Whether to use a decomposed control vector + + Returns + ------- + d_p : ndarray[np.float64, ndim=1] + CG descent direction + Array shape: (dim_cvec_p) + j_tot : double + on exit: Value of cost function + gradj : ndarray[np.float64, ndim=1] + on exit: gradient of J + Array shape: (dim_cvec_p) + hessjd : ndarray[np.float64, ndim=1] + on exit: Hessian of J times d_p + Array shape: (dim_cvec_p) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] d_p_np = np.asarray(d_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] gradj_np = np.zeros((dim_cvec_p), dtype=np.float64, order="F") + cdef double [::1] gradj = gradj_np + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] hessjd_np = np.zeros((dim_cvec_p), dtype=np.float64, order="F") + cdef double [::1] hessjd = hessjd_np + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + cdef double j_tot + with nogil: + c__pdaf_3dvar_costf_cg_cvt(&step, &iter, &dim_p, &dim_cvec_p, + &dim_obs_p, &obs_p[0], &dy_p[0], + &v_p[0], &d_p[0], &j_tot, &gradj[0], + &hessjd[0], pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, &opt_parallel) + + return d_p_np, j_tot, gradj_np, hessjd_np + + +def lknetf_analysis_t(int domain_p, int step, int dim_l, + int dim_obs_l, int dim_ens, double [::1] state_l, + double [::1,:] ens_l, double [::1,:] hx_l, double [::1] hxbar_l, + double [::1] obs_l, double [::1,:] rndmat, double forget, + py__prodrinva_l_pdaf, py__init_obsvar_l_pdaf, py__likelihood_l_pdaf, + int screen, int type_forget, double [::1] eff_dimens, int type_hyb, + double hyb_g, double hyb_k, double [::1] gamma, + double [::1] skew_mabs, double [::1] kurt_mabs, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + step : int + Current time step + dim_l : int + State dimension on local analysis domain + dim_obs_l : int + Size of obs. vector on local ana. domain + dim_ens : int + Size of ensemble + state_l : ndarray[np.float64, ndim=1] + local forecast state + Array shape: (dim_l) + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + hx_l : ndarray[np.float64, ndim=2] + local observed state ens. + Array shape: (dim_obs_l, dim_ens) + hxbar_l : ndarray[np.float64, ndim=1] + local observed ens. mean + Array shape: (dim_obs_l) + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_l) + rndmat : ndarray[np.float64, ndim=2] + Global random rotation matrix + Array shape: (dim_ens, dim_ens) + forget : double + Forgetting factor + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A for local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__likelihood_l_pdaf : Callable + Provide likelihood of an ensemble state + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + screen : int + Verbosity flag + type_forget : int + Type of forgetting factor + eff_dimens : ndarray[np.float64, ndim=1] + Effective ensemble size + Array shape: (1) + type_hyb : int + Type of hybrid weight + hyb_g : double + Prescribed hybrid weight for state transformation + hyb_k : double + Scale factor kappa (for type_hyb 3 and 4) + gamma : ndarray[np.float64, ndim=1] + Hybrid weight for state transformation + Array shape: (1) + skew_mabs : ndarray[np.float64, ndim=1] + Mean absolute skewness + Array shape: (1) + kurt_mabs : ndarray[np.float64, ndim=1] + Mean absolute kurtosis + Array shape: (1) + flag : int + Status flag + + Returns + ------- + state_l : ndarray[np.float64, ndim=1] + local forecast state + Array shape: (dim_l) + ainv_l : ndarray[np.float64, ndim=2] + on exit: local weight matrix for ensemble transformation + Array shape: (dim_ens, dim_ens) + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + rndmat : ndarray[np.float64, ndim=2] + Global random rotation matrix + Array shape: (dim_ens, dim_ens) + forget : double + Forgetting factor + eff_dimens : ndarray[np.float64, ndim=1] + Effective ensemble size + Array shape: (1) + gamma : ndarray[np.float64, ndim=1] + Hybrid weight for state transformation + Array shape: (1) + skew_mabs : ndarray[np.float64, ndim=1] + Mean absolute skewness + Array shape: (1) + kurt_mabs : ndarray[np.float64, ndim=1] + Mean absolute kurtosis + Array shape: (1) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_l_np = np.asarray(state_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_l_np = np.zeros((dim_ens, dim_ens), dtype=np.float64, order="F") + cdef double [::1,:] ainv_l = ainv_l_np + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_l_np = np.asarray(ens_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] rndmat_np = np.asarray(rndmat, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] eff_dimens_np = np.asarray(eff_dimens, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] gamma_np = np.asarray(gamma, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] skew_mabs_np = np.asarray(skew_mabs, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] kurt_mabs_np = np.asarray(kurt_mabs, dtype=np.float64, order="F") + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + with nogil: + c__pdaf_lknetf_analysis_t(&domain_p, &step, &dim_l, &dim_obs_l, + &dim_ens, &state_l[0], &ainv_l[0,0], + &ens_l[0,0], &hx_l[0,0], &hxbar_l[0], + &obs_l[0], &rndmat[0,0], &forget, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, &screen, + &type_forget, &eff_dimens[0], &type_hyb, + &hyb_g, &hyb_k, &gamma[0], &skew_mabs[0], + &kurt_mabs[0], &flag) + + return state_l_np, ainv_l_np, ens_l_np, rndmat_np, forget, eff_dimens_np, gamma_np, skew_mabs_np, kurt_mabs_np, flag + + +def get_ensstats(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + cdef CFI_cdesc_rank1 skew_ptr_cfi + cdef CFI_cdesc_t *skew_ptr_ptr = &skew_ptr_cfi + cdef CFI_cdesc_rank1 kurt_ptr_cfi + cdef CFI_cdesc_t *kurt_ptr_ptr = &kurt_ptr_cfi + cdef int status + with nogil: + c__pdaf_get_ensstats(skew_ptr_ptr, kurt_ptr_ptr, &status) + + cdef CFI_index_t skew_ptr_subscripts[1] + skew_ptr_subscripts[0] = 0 + cdef double * skew_ptr_ptr_np + skew_ptr_ptr_np = CFI_address(skew_ptr_ptr, skew_ptr_subscripts) + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] skew_ptr_np = np.asarray( skew_ptr_ptr_np, order="F") + cdef CFI_index_t kurt_ptr_subscripts[1] + kurt_ptr_subscripts[0] = 0 + cdef double * kurt_ptr_ptr_np + kurt_ptr_ptr_np = CFI_address(kurt_ptr_ptr, kurt_ptr_subscripts) + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] kurt_ptr_np = np.asarray( kurt_ptr_ptr_np, order="F") + return skew_ptr_np, kurt_ptr_np, status + + +def estkf_init(int subtype, int [::1] param_int, int dim_pint, + double [::1] param_real, int dim_preal, int verbose, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + dim_pint : int + Number of integer parameters + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + dim_preal : int + Number of real parameters + verbose : int + Control screen output + outflag : int + Status flag + + Returns + ------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + ensemblefilter : bint + Is the chosen filter ensemble-based? + fixedbasis : bint + Does the filter run with fixed error-space basis? + outflag : int + Status flag + """ + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_int_np = np.asarray(param_int, dtype=np.intc, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_real_np = np.asarray(param_real, dtype=np.float64, order="F") + cdef bint ensemblefilter + cdef bint fixedbasis + with nogil: + c__pdaf_estkf_init(&subtype, ¶m_int[0], &dim_pint, + ¶m_real[0], &dim_preal, &ensemblefilter, + &fixedbasis, &verbose, &outflag) + + return subtype, param_int_np, param_real_np, ensemblefilter, fixedbasis, outflag + + +def estkf_alloc(int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + with nogil: + c__pdaf_estkf_alloc(&outflag) + + return outflag + + +def estkf_config(int subtype, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + verbose : int + Control screen output + + Returns + ------- + subtype : int + Sub-type of filter + """ + with nogil: + c__pdaf_estkf_config(&subtype, &verbose) + + return subtype + + +def estkf_set_iparam(int id, int value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : int + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_estkf_set_iparam(&id, &value, &flag) + + return flag + + +def estkf_set_rparam(int id, double value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : double + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_estkf_set_rparam(&id, &value, &flag) + + return flag + + +def estkf_options(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdaf_estkf_options() + + + +def estkf_memtime(int printtype): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + printtype : int + Type of screen output: + + Returns + ------- + """ + with nogil: + c__pdaf_estkf_memtime(&printtype) + + + +def gen_obs(int step, int dim_p, int dim_ens, double [::1] state_p, + double [::1,:] ainv, double [::1,:] ens_p, py__init_dim_obs_f_pdaf, + py__obs_op_f_pdaf, py__get_obs_f_pdaf, py__init_obserr_f_pdaf, + py__prepoststep_pdaf, int screen, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (dim_ens, dim_ens) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__get_obs_f_pdaf : Callable + Provide observation vector to user + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Size of the full observation vector + + Callback Returns + ---------------- + observation_f : ndarray[np.float64, ndim=1] + Full vector of synthetic observations (process-local) + Array shape: (dim_obs_f) + + py__init_obserr_f_pdaf : Callable + Initialize vector of observation error standard deviations + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Full dimension of observation vector + obs_f : ndarray[np.float64, ndim=1] + Full observation vector + Array shape: (dim_obs_f) + + Callback Returns + ---------------- + obserr_f : ndarray[np.float64, ndim=1] + Full observation error stddev + Array shape: (dim_obs_f) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + screen : int + Verbosity flag + flag : int + Status flag + + Returns + ------- + dim_obs_f : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (dim_ens, dim_ens) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_np = np.asarray(ainv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.get_obs_f_pdaf = py__get_obs_f_pdaf + pdaf_cb.init_obserr_f_pdaf = py__init_obserr_f_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int dim_obs_f + with nogil: + c__pdaf_gen_obs(&step, &dim_p, &dim_obs_f, &dim_ens, &state_p[0], + &ainv[0,0], &ens_p[0,0], + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__get_obs_f_pdaf, + pdaf_cb.c__init_obserr_f_pdaf, + pdaf_cb.c__prepoststep_pdaf, &screen, &flag) + + return dim_obs_f, state_p_np, ainv_np, ens_p_np, flag + + +def obs_init(int step, int dim_p, int dim_ens, int dim_obs_p, + double [::1] state_p, double [::1,:] ens_p, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, int screen, int debug, + bint do_ens_mean, bint do_init_dim, bint do_hx, bint do_hxbar, + bint do_init_obs): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + screen : int + Verbosity flag + debug : int + Flag for writing debug output + do_ens_mean : bint + Whether to compute ensemble mean + do_init_dim : bint + Whether to call U_init_dim_obs + do_hx : bint + Whether to initialize HX_p + do_hxbar : bint + Whether to initialize HXbar + do_init_obs : bint + Whether to initialize obs_p + + Returns + ------- + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + with nogil: + c__pdafobs_init(&step, &dim_p, &dim_ens, &dim_obs_p, &state_p[0], + &ens_p[0,0], pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, pdaf_cb.c__init_obs_pdaf, + &screen, &debug, &do_ens_mean, &do_init_dim, + &do_hx, &do_hxbar, &do_init_obs) + + return dim_obs_p, state_p_np, ens_p_np + + +def obs_init_local(int domain_p, int step, int dim_ens, + py__init_dim_obs_l_pdaf, py__g2l_obs_pdaf, py__init_obs_l_pdaf, int debug): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + step : int + Current time step + dim_ens : int + Size of ensemble + py__init_dim_obs_l_pdaf : Callable + Init. dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + debug : int + Flag for writing debug output + + Returns + ------- + dim_obs_l : int + Size of local observation vector + dim_obs_f : int + PE-local dimension of observation vector + """ + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + cdef int dim_obs_l + cdef int dim_obs_f + with nogil: + c__pdafobs_init_local(&domain_p, &step, &dim_obs_l, &dim_obs_f, + &dim_ens, pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, &debug) + + return dim_obs_l, dim_obs_f + + +def obs_init_obsvars(int step, int dim_obs_p, py__init_obsvars_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_obs_p : int + PE-local dimension of observation vector + py__init_obsvars_pdaf : Callable + Initialize vector of observation error variances + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Dimension of full observation vector + + Callback Returns + ---------------- + var_f : ndarray[np.float64, ndim=1] + vector of observation error variances + Array shape: (dim_obs_f) + + + Returns + ------- + """ + pdaf_cb.init_obsvars_pdaf = py__init_obsvars_pdaf + with nogil: + c__pdafobs_init_obsvars(&step, &dim_obs_p, pdaf_cb.c__init_obsvars_pdaf) + + + +def obs_dealloc(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdafobs_dealloc() + + + +def obs_dealloc_local(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdafobs_dealloc_local() + + + +def netf_init(int subtype, int [::1] param_int, int dim_pint, + double [::1] param_real, int dim_preal, int verbose, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + dim_pint : int + Number of integer parameters + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + dim_preal : int + Number of real parameters + verbose : int + Control screen output + outflag : int + Status flag + + Returns + ------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + ensemblefilter : bint + Is the chosen filter ensemble-based? + fixedbasis : bint + Does the filter run with fixed error-space basis? + outflag : int + Status flag + """ + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_int_np = np.asarray(param_int, dtype=np.intc, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_real_np = np.asarray(param_real, dtype=np.float64, order="F") + cdef bint ensemblefilter + cdef bint fixedbasis + with nogil: + c__pdaf_netf_init(&subtype, ¶m_int[0], &dim_pint, + ¶m_real[0], &dim_preal, &ensemblefilter, + &fixedbasis, &verbose, &outflag) + + return subtype, param_int_np, param_real_np, ensemblefilter, fixedbasis, outflag + + +def netf_alloc(int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + with nogil: + c__pdaf_netf_alloc(&outflag) + + return outflag + + +def netf_config(int subtype, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + verbose : int + Control screen output + + Returns + ------- + subtype : int + Sub-type of filter + """ + with nogil: + c__pdaf_netf_config(&subtype, &verbose) + + return subtype + + +def netf_set_iparam(int id, int value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : int + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_netf_set_iparam(&id, &value, &flag) + + return flag + + +def netf_set_rparam(int id, double value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : double + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_netf_set_rparam(&id, &value, &flag) + + return flag + + +def netf_options(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdaf_netf_options() + + + +def netf_memtime(int printtype): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + printtype : int + Type of screen output: + + Returns + ------- + """ + with nogil: + c__pdaf_netf_memtime(&printtype) + + + +def lenkf_init(int subtype, int [::1] param_int, int dim_pint, + double [::1] param_real, int dim_preal, int verbose, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + dim_pint : int + Number of integer parameters + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + dim_preal : int + Number of real parameters + verbose : int + Control screen output + outflag : int + Status flag + + Returns + ------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + ensemblefilter : bint + Is the chosen filter ensemble-based? + fixedbasis : bint + Does the filter run with fixed error-space basis? + outflag : int + Status flag + """ + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_int_np = np.asarray(param_int, dtype=np.intc, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_real_np = np.asarray(param_real, dtype=np.float64, order="F") + cdef bint ensemblefilter + cdef bint fixedbasis + with nogil: + c__pdaf_lenkf_init(&subtype, ¶m_int[0], &dim_pint, + ¶m_real[0], &dim_preal, &ensemblefilter, + &fixedbasis, &verbose, &outflag) + + return subtype, param_int_np, param_real_np, ensemblefilter, fixedbasis, outflag + + +def lenkf_alloc(int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + with nogil: + c__pdaf_lenkf_alloc(&outflag) + + return outflag + + +def lenkf_config(int subtype, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + verbose : int + Control screen output + + Returns + ------- + subtype : int + Sub-type of filter + """ + with nogil: + c__pdaf_lenkf_config(&subtype, &verbose) + + return subtype + + +def lenkf_set_iparam(int id, int value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : int + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_lenkf_set_iparam(&id, &value, &flag) + + return flag + + +def lenkf_set_rparam(int id, double value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : double + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_lenkf_set_rparam(&id, &value, &flag) + + return flag + + +def lenkf_options(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdaf_lenkf_options() + + + +def lenkf_memtime(int printtype): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + printtype : int + Type of screen output: + + Returns + ------- + """ + with nogil: + c__pdaf_lenkf_memtime(&printtype) + + + +def lseik_init(int subtype, int [::1] param_int, int dim_pint, + double [::1] param_real, int dim_preal, int verbose, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + dim_pint : int + Number of integer parameters + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + dim_preal : int + Number of real parameters + verbose : int + Control screen output + outflag : int + Status flag + + Returns + ------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + ensemblefilter : bint + Is the chosen filter ensemble-based? + fixedbasis : bint + Does the filter run with fixed error-space basis? + outflag : int + Status flag + """ + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_int_np = np.asarray(param_int, dtype=np.intc, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_real_np = np.asarray(param_real, dtype=np.float64, order="F") + cdef bint ensemblefilter + cdef bint fixedbasis + with nogil: + c__pdaf_lseik_init(&subtype, ¶m_int[0], &dim_pint, + ¶m_real[0], &dim_preal, &ensemblefilter, + &fixedbasis, &verbose, &outflag) + + return subtype, param_int_np, param_real_np, ensemblefilter, fixedbasis, outflag + + +def lseik_alloc(int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + with nogil: + c__pdaf_lseik_alloc(&outflag) + + return outflag + + +def lseik_config(int subtype, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + verbose : int + Control screen output + + Returns + ------- + subtype : int + Sub-type of filter + """ + with nogil: + c__pdaf_lseik_config(&subtype, &verbose) + + return subtype + + +def lseik_set_iparam(int id, int value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : int + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_lseik_set_iparam(&id, &value, &flag) + + return flag + + +def lseik_set_rparam(int id, double value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : double + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_lseik_set_rparam(&id, &value, &flag) + + return flag + + +def lseik_options(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdaf_lseik_options() + + + +def lseik_memtime(int printtype): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + printtype : int + Type of screen output: + + Returns + ------- + """ + with nogil: + c__pdaf_lseik_memtime(&printtype) + + + +def etkf_init(int subtype, int [::1] param_int, int dim_pint, + double [::1] param_real, int dim_preal, int verbose, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + dim_pint : int + Number of integer parameters + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + dim_preal : int + Number of real parameters + verbose : int + Control screen output + outflag : int + Status flag + + Returns + ------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + ensemblefilter : bint + Is the chosen filter ensemble-based? + fixedbasis : bint + Does the filter run with fixed error-space basis? + outflag : int + Status flag + """ + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_int_np = np.asarray(param_int, dtype=np.intc, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_real_np = np.asarray(param_real, dtype=np.float64, order="F") + cdef bint ensemblefilter + cdef bint fixedbasis + with nogil: + c__pdaf_etkf_init(&subtype, ¶m_int[0], &dim_pint, + ¶m_real[0], &dim_preal, &ensemblefilter, + &fixedbasis, &verbose, &outflag) + + return subtype, param_int_np, param_real_np, ensemblefilter, fixedbasis, outflag + + +def etkf_alloc(int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + with nogil: + c__pdaf_etkf_alloc(&outflag) + + return outflag + + +def etkf_config(int subtype, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + verbose : int + Control screen output + + Returns + ------- + subtype : int + Sub-type of filter + """ + with nogil: + c__pdaf_etkf_config(&subtype, &verbose) + + return subtype + + +def etkf_set_iparam(int id, int value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : int + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_etkf_set_iparam(&id, &value, &flag) + + return flag + + +def etkf_set_rparam(int id, double value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : double + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_etkf_set_rparam(&id, &value, &flag) + + return flag + + +def etkf_options(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdaf_etkf_options() + + + +def etkf_memtime(int printtype): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + printtype : int + Type of screen output: + + Returns + ------- + """ + with nogil: + c__pdaf_etkf_memtime(&printtype) + + + +def lenkf_update(int step, int dim_p, int dim_ens, + double [::1] state_p, double [::1,:] ens_p, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__add_obs_err_pdaf, py__init_obs_pdaf, + py__init_obs_covar_pdaf, py__prepoststep_pdaf, py__localize_covar_pdaf, + int screen, int subtype, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of state ensemble + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__add_obs_err_pdaf : Callable + Add observation error covariance matrix + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Dimension of observation vector + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_covar_pdaf : Callable + Initialize observation error covariance matrix + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs : int + Global size of observation vector + dim_obs_p : int + Size of process-local observation vector + obs_p : ndarray[np.float64, ndim=1] + Process-local vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + covar : ndarray[np.float64, ndim=2] + Observation error covariance matrix + Array shape: (dim_obs_p,dim_obs_p) + isdiag : bint + + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__localize_covar_pdaf : Callable + Apply localization to HP and HPH^T + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + dim_obs : int + number of observations + hp_p : ndarray[np.float64, ndim=2] + pe local part of matrix hp + Array shape: (dim_obs, dim_p) + hph : ndarray[np.float64, ndim=2] + matrix hph + Array shape: (dim_obs, dim_obs) + + Callback Returns + ---------------- + hp_p : ndarray[np.float64, ndim=2] + pe local part of matrix hp + Array shape: (dim_obs, dim_p) + hph : ndarray[np.float64, ndim=2] + matrix hph + Array shape: (dim_obs, dim_obs) + + screen : int + Verbosity flag + subtype : int + Specification of filter subtype + flag : int + Status flag + + Returns + ------- + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.localize_covar_pdaf = py__localize_covar_pdaf + cdef int dim_obs_p + with nogil: + c__pdaflenkf_update(&step, &dim_p, &dim_obs_p, &dim_ens, + &state_p[0], &ens_p[0,0], + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__localize_covar_pdaf, &screen, + &subtype, &flag) + + return dim_obs_p, state_p_np, ens_p_np, flag + + +def pf_init(int subtype, int [::1] param_int, int dim_pint, + double [::1] param_real, int dim_preal, int verbose, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + dim_pint : int + Number of integer parameters + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + dim_preal : int + Number of real parameters + verbose : int + Control screen output + outflag : int + Status flag + + Returns + ------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + ensemblefilter : bint + Is the chosen filter ensemble-based? + fixedbasis : bint + Does the filter run with fixed error-space basis? + outflag : int + Status flag + """ + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_int_np = np.asarray(param_int, dtype=np.intc, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_real_np = np.asarray(param_real, dtype=np.float64, order="F") + cdef bint ensemblefilter + cdef bint fixedbasis + with nogil: + c__pdaf_pf_init(&subtype, ¶m_int[0], &dim_pint, ¶m_real[0], + &dim_preal, &ensemblefilter, &fixedbasis, &verbose, + &outflag) + + return subtype, param_int_np, param_real_np, ensemblefilter, fixedbasis, outflag + + +def pf_alloc(int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + with nogil: + c__pdaf_pf_alloc(&outflag) + + return outflag + + +def pf_config(int subtype, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + verbose : int + Control screen output + + Returns + ------- + subtype : int + Sub-type of filter + """ + with nogil: + c__pdaf_pf_config(&subtype, &verbose) + + return subtype + + +def pf_set_iparam(int id, int value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : int + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_pf_set_iparam(&id, &value, &flag) + + return flag + + +def pf_set_rparam(int id, double value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : double + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_pf_set_rparam(&id, &value, &flag) + + return flag + + +def pf_options(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdaf_pf_options() + + + +def pf_memtime(int printtype): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + printtype : int + Type of screen output: + + Returns + ------- + """ + with nogil: + c__pdaf_pf_memtime(&printtype) + + + +def lknetf_ana_letkft(int domain_p, int step, int dim_l, + int dim_obs_l, int dim_ens, double [::1] state_l, + double [::1,:] ens_l, double [::1,:] hz_l, double [::1] hxbar_l, + double [::1] obs_l, double [::1,:] rndmat, double forget, + py__prodrinva_hyb_l_pdaf, py__init_obsvar_l_pdaf, double [::1] gamma, + int screen, int type_forget, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + step : int + Current time step + dim_l : int + State dimension on local analysis domain + dim_obs_l : int + Size of obs. vector on local ana. domain + dim_ens : int + Size of ensemble + state_l : ndarray[np.float64, ndim=1] + local forecast state + Array shape: (dim_l) + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + hz_l : ndarray[np.float64, ndim=2] + PE-local full observed state ens. + Array shape: (dim_obs_l, dim_ens) + hxbar_l : ndarray[np.float64, ndim=1] + local observed ens. mean + Array shape: (dim_obs_l) + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_l) + rndmat : ndarray[np.float64, ndim=2] + Global random rotation matrix + Array shape: (dim_ens, dim_ens) + forget : double + Forgetting factor + py__prodrinva_hyb_l_pdaf : Callable + Provide product R^-1 A for local analysis domain including hybrid weight + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + dim_ens : int + Number of the columns in the matrix processes here. This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, dim_ens) + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + gamma : ndarray[np.float64, ndim=1] + Hybrid weight for state transformation + Array shape: (1) + screen : int + Verbosity flag + type_forget : int + Type of forgetting factor + flag : int + Status flag + + Returns + ------- + state_l : ndarray[np.float64, ndim=1] + local forecast state + Array shape: (dim_l) + ainv_l : ndarray[np.float64, ndim=2] + local weight matrix for ensemble transformation + Array shape: (dim_ens, dim_ens) + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + hz_l : ndarray[np.float64, ndim=2] + PE-local full observed state ens. + Array shape: (dim_obs_l, dim_ens) + rndmat : ndarray[np.float64, ndim=2] + Global random rotation matrix + Array shape: (dim_ens, dim_ens) + forget : double + Forgetting factor + gamma : ndarray[np.float64, ndim=1] + Hybrid weight for state transformation + Array shape: (1) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_l_np = np.asarray(state_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_l_np = np.zeros((dim_ens, dim_ens), dtype=np.float64, order="F") + cdef double [::1,:] ainv_l = ainv_l_np + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_l_np = np.asarray(ens_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hz_l_np = np.asarray(hz_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] rndmat_np = np.asarray(rndmat, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] gamma_np = np.asarray(gamma, dtype=np.float64, order="F") + pdaf_cb.prodrinva_hyb_l_pdaf = py__prodrinva_hyb_l_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + with nogil: + c__pdaf_lknetf_ana_letkft(&domain_p, &step, &dim_l, &dim_obs_l, + &dim_ens, &state_l[0], &ainv_l[0,0], + &ens_l[0,0], &hz_l[0,0], &hxbar_l[0], + &obs_l[0], &rndmat[0,0], &forget, + pdaf_cb.c__prodrinva_hyb_l_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, &gamma[0], + &screen, &type_forget, &flag) + + return state_l_np, ainv_l_np, ens_l_np, hz_l_np, rndmat_np, forget, gamma_np, flag + + +def lknetf_ana_lnetf(int domain_p, int step, int dim_l, int dim_obs_l, + int dim_ens, double [::1,:] ens_l, double [::1,:] hx_l, + double [::1,:] rndmat, double [::1] obs_l, py__likelihood_hyb_l_pdaf, + int cnt_small_svals, double [::1] n_eff_all, double [::1] gamma, + int screen, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + step : int + Current time step + dim_l : int + State dimension on local analysis domain + dim_obs_l : int + Size of obs. vector on local ana. domain + dim_ens : int + Size of ensemble + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + hx_l : ndarray[np.float64, ndim=2] + local observed state ens. + Array shape: (dim_obs_l, dim_ens) + rndmat : ndarray[np.float64, ndim=2] + Global random rotation matrix + Array shape: (dim_ens, dim_ens) + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_l) + py__likelihood_hyb_l_pdaf : Callable + Compute observation likelihood for an ensemble member with hybrid weight + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + cnt_small_svals : int + Number of small eigen values + n_eff_all : ndarray[np.float64, ndim=1] + Effective ensemble size + Array shape: (1) + gamma : ndarray[np.float64, ndim=1] + Hybrid weight for state transformation + Array shape: (1) + screen : int + Verbosity flag + flag : int + Status flag + + Returns + ------- + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + cnt_small_svals : int + Number of small eigen values + n_eff_all : ndarray[np.float64, ndim=1] + Effective ensemble size + Array shape: (1) + gamma : ndarray[np.float64, ndim=1] + Hybrid weight for state transformation + Array shape: (1) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_l_np = np.asarray(ens_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] n_eff_all_np = np.asarray(n_eff_all, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] gamma_np = np.asarray(gamma, dtype=np.float64, order="F") + pdaf_cb.likelihood_hyb_l_pdaf = py__likelihood_hyb_l_pdaf + with nogil: + c__pdaf_lknetf_ana_lnetf(&domain_p, &step, &dim_l, &dim_obs_l, + &dim_ens, &ens_l[0,0], &hx_l[0,0], + &rndmat[0,0], &obs_l[0], + pdaf_cb.c__likelihood_hyb_l_pdaf, + &cnt_small_svals, &n_eff_all[0], + &gamma[0], &screen, &flag) + + return ens_l_np, cnt_small_svals, n_eff_all_np, gamma_np, flag + + +def enkf_ana_rsm(int step, int dim_p, int dim_obs_p, int dim_obs, int dim_ens, + int rank_ana, double [::1] state_p, double [::1,:] ens_p, + double [::1,:] hx_p, double [::1] hxbar_p, double [::1] obs_p, + py__add_obs_err_pdaf, py__init_obs_covar_pdaf, int screen, int debug, + int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_obs_p : int + PE-local dimension of observation vector + dim_obs : int + Global dimension of observation vector + dim_ens : int + Size of state ensemble + rank_ana : int + Rank to be considered for inversion of HPH + state_p : ndarray[np.float64, ndim=1] + PE-local ensemble mean state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hx_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble + Array shape: (dim_obs_p, dim_ens) + hxbar_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + py__add_obs_err_pdaf : Callable + Add observation error covariance matrix + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Dimension of observation vector + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + py__init_obs_covar_pdaf : Callable + Initialize observation error covariance matrix + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs : int + Global size of observation vector + dim_obs_p : int + Size of process-local observation vector + obs_p : ndarray[np.float64, ndim=1] + Process-local vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + covar : ndarray[np.float64, ndim=2] + Observation error covariance matrix + Array shape: (dim_obs_p,dim_obs_p) + isdiag : bint + + + screen : int + Verbosity flag + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + PE-local ensemble mean state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + with nogil: + c__pdaf_enkf_ana_rsm(&step, &dim_p, &dim_obs_p, &dim_obs, &dim_ens, + &rank_ana, &state_p[0], &ens_p[0,0], + &hx_p[0,0], &hxbar_p[0], &obs_p[0], + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, &screen, + &debug, &flag) + + return state_p_np, ens_p_np, flag + + +def lknetf_init(int subtype, int [::1] param_int, int dim_pint, + double [::1] param_real, int dim_preal, int verbose, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + dim_pint : int + Number of integer parameters + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + dim_preal : int + Number of real parameters + verbose : int + Control screen output + outflag : int + Status flag + + Returns + ------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + ensemblefilter : bint + Is the chosen filter ensemble-based? + fixedbasis : bint + Does the filter run with fixed error-space basis? + outflag : int + Status flag + """ + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_int_np = np.asarray(param_int, dtype=np.intc, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_real_np = np.asarray(param_real, dtype=np.float64, order="F") + cdef bint ensemblefilter + cdef bint fixedbasis + with nogil: + c__pdaf_lknetf_init(&subtype, ¶m_int[0], &dim_pint, + ¶m_real[0], &dim_preal, &ensemblefilter, + &fixedbasis, &verbose, &outflag) + + return subtype, param_int_np, param_real_np, ensemblefilter, fixedbasis, outflag + + +def lknetf_alloc(int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + with nogil: + c__pdaf_lknetf_alloc(&outflag) + + return outflag + + +def lknetf_config(int subtype, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + verbose : int + Control screen output + + Returns + ------- + subtype : int + Sub-type of filter + """ + with nogil: + c__pdaf_lknetf_config(&subtype, &verbose) + + return subtype + + +def lknetf_set_iparam(int id, int value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : int + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_lknetf_set_iparam(&id, &value, &flag) + + return flag + + +def lknetf_set_rparam(int id, double value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : double + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_lknetf_set_rparam(&id, &value, &flag) + + return flag + + +def lknetf_options(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdaf_lknetf_options() + + + +def lknetf_memtime(int printtype): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + printtype : int + Type of screen output: + + Returns + ------- + """ + with nogil: + c__pdaf_lknetf_memtime(&printtype) + + + +def lknetf_alpha_neff(int dim_ens, double [::1] weights, double hlimit, + double alpha): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_ens : int + Size of ensemble + weights : ndarray[np.float64, ndim=1] + Weights + Array shape: (dim_ens) + hlimit : double + Minimum of n_eff / N + alpha : double + hybrid weight + + Returns + ------- + alpha : double + hybrid weight + """ + with nogil: + c__pdaf_lknetf_alpha_neff(&dim_ens, &weights[0], &hlimit, &alpha) + + return alpha + + +def lknetf_compute_gamma(int domain_p, int step, int dim_obs_l, + int dim_ens, double [::1,:] hx_l, double [::1] hxbar_l, + double [::1] obs_l, int type_hyb, double hyb_g, double hyb_k, + double [::1] gamma, double [::1] n_eff_out, double [::1] skew_mabs, + double [::1] kurt_mabs, py__likelihood_l_pdaf, int screen, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + step : int + Current time step + dim_obs_l : int + Size of obs. vector on local ana. domain + dim_ens : int + Size of ensemble + hx_l : ndarray[np.float64, ndim=2] + local observed state ens. + Array shape: (dim_obs_l, dim_ens) + hxbar_l : ndarray[np.float64, ndim=1] + local mean observed ensemble + Array shape: (dim_obs_l) + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_l) + type_hyb : int + Type of hybrid weight + hyb_g : double + Prescribed hybrid weight for state transformation + hyb_k : double + Hybrid weight for covariance transformation + gamma : ndarray[np.float64, ndim=1] + Hybrid weight for state transformation + Array shape: (1) + n_eff_out : ndarray[np.float64, ndim=1] + Effective ensemble size + Array shape: (1) + skew_mabs : ndarray[np.float64, ndim=1] + Mean absolute skewness + Array shape: (1) + kurt_mabs : ndarray[np.float64, ndim=1] + Mean absolute kurtosis + Array shape: (1) + py__likelihood_l_pdaf : Callable + Compute observation likelihood for an ensemble member + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + screen : int + Verbosity flag + flag : int + Status flag + + Returns + ------- + gamma : ndarray[np.float64, ndim=1] + Hybrid weight for state transformation + Array shape: (1) + n_eff_out : ndarray[np.float64, ndim=1] + Effective ensemble size + Array shape: (1) + skew_mabs : ndarray[np.float64, ndim=1] + Mean absolute skewness + Array shape: (1) + kurt_mabs : ndarray[np.float64, ndim=1] + Mean absolute kurtosis + Array shape: (1) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] gamma_np = np.asarray(gamma, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] n_eff_out_np = np.asarray(n_eff_out, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] skew_mabs_np = np.asarray(skew_mabs, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] kurt_mabs_np = np.asarray(kurt_mabs, dtype=np.float64, order="F") + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + with nogil: + c__pdaf_lknetf_compute_gamma(&domain_p, &step, &dim_obs_l, + &dim_ens, &hx_l[0,0], &hxbar_l[0], + &obs_l[0], &type_hyb, &hyb_g, &hyb_k, + &gamma[0], &n_eff_out[0], + &skew_mabs[0], &kurt_mabs[0], + pdaf_cb.c__likelihood_l_pdaf, &screen, + &flag) + + return gamma_np, n_eff_out_np, skew_mabs_np, kurt_mabs_np, flag + + +def lknetf_set_gamma(int domain_p, int dim_obs_l, int dim_ens, + double [::1,:] hx_l, double [::1] hxbar_l, double [::1] weights, + int type_hyb, double hyb_g, double hyb_k, double [::1] gamma, + double [::1] n_eff_out, double [::1] maskew, double [::1] makurt, + int screen, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + dim_obs_l : int + Size of obs. vector on local ana. domain + dim_ens : int + Size of ensemble + hx_l : ndarray[np.float64, ndim=2] + local observed state ens. + Array shape: (dim_obs_l, dim_ens) + hxbar_l : ndarray[np.float64, ndim=1] + local mean observed ensemble + Array shape: (dim_obs_l) + weights : ndarray[np.float64, ndim=1] + Weight vector + Array shape: (dim_ens) + type_hyb : int + Type of hybrid weight + hyb_g : double + Prescribed hybrid weight for state transformation + hyb_k : double + Scale factor kappa (for type_hyb 3 and 4) + gamma : ndarray[np.float64, ndim=1] + Hybrid weight for state transformation + Array shape: (1) + n_eff_out : ndarray[np.float64, ndim=1] + Effective ensemble size + Array shape: (1) + maskew : ndarray[np.float64, ndim=1] + Mean absolute skewness + Array shape: (1) + makurt : ndarray[np.float64, ndim=1] + Mean absolute kurtosis + Array shape: (1) + screen : int + Verbosity flag + flag : int + Status flag + + Returns + ------- + gamma : ndarray[np.float64, ndim=1] + Hybrid weight for state transformation + Array shape: (1) + n_eff_out : ndarray[np.float64, ndim=1] + Effective ensemble size + Array shape: (1) + maskew : ndarray[np.float64, ndim=1] + Mean absolute skewness + Array shape: (1) + makurt : ndarray[np.float64, ndim=1] + Mean absolute kurtosis + Array shape: (1) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] gamma_np = np.asarray(gamma, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] n_eff_out_np = np.asarray(n_eff_out, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] maskew_np = np.asarray(maskew, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] makurt_np = np.asarray(makurt, dtype=np.float64, order="F") + with nogil: + c__pdaf_lknetf_set_gamma(&domain_p, &dim_obs_l, &dim_ens, + &hx_l[0,0], &hxbar_l[0], &weights[0], + &type_hyb, &hyb_g, &hyb_k, &gamma[0], + &n_eff_out[0], &maskew[0], &makurt[0], + &screen, &flag) + + return gamma_np, n_eff_out_np, maskew_np, makurt_np, flag + + +def lknetf_reset_gamma(double gamma_in): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + gamma_in : double + Prescribed hybrid weight + + Returns + ------- + """ + with nogil: + c__pdaf_lknetf_reset_gamma(&gamma_in) + + + +def hyb3dvar_analysis_cvt(int step, int dim_p, int dim_obs_p, + int dim_ens, int dim_cvec, int dim_cvec_ens, double beta_3dvar, + double [::1] state_p, double [::1,:] ens_p, double [::1] state_inc_p, + double [::1] hxbar_p, double [::1] obs_p, py__prodrinva_pdaf, + py__cvt_pdaf, py__cvt_adj_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, int screen, int type_opt, + int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_obs_p : int + PE-local dimension of observation vector + dim_ens : int + Size of ensemble + dim_cvec : int + Size of control vector (parameterized part) + dim_cvec_ens : int + Size of control vector (ensemble part) + beta_3dvar : double + Hybrid weight for hybrid 3D-Var + state_p : ndarray[np.float64, ndim=1] + on exit: PE-local forecast state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + state_inc_p : ndarray[np.float64, ndim=1] + PE-local state analysis increment + Array shape: (dim_p) + hxbar_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector (parameterized) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix (parameterized) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + screen : int + Verbosity flag + type_opt : int + Type of minimizer for 3DVar + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + on exit: PE-local forecast state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + state_inc_p : ndarray[np.float64, ndim=1] + PE-local state analysis increment + Array shape: (dim_p) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_inc_p_np = np.asarray(state_inc_p, dtype=np.float64, order="F") + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + with nogil: + c__pdafhyb3dvar_analysis_cvt(&step, &dim_p, &dim_obs_p, &dim_ens, + &dim_cvec, &dim_cvec_ens, &beta_3dvar, + &state_p[0], &ens_p[0,0], + &state_inc_p[0], &hxbar_p[0], + &obs_p[0], pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, &screen, + &type_opt, &debug, &flag) + + return state_p_np, ens_p_np, state_inc_p_np, flag + + +def _3dvar_analysis_cvt(int step, int dim_p, int dim_obs_p, + int dim_cvec, double [::1] hxbar_p, double [::1] obs_p, + py__prodrinva_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, int screen, int type_opt, + int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_obs_p : int + PE-local dimension of observation vector + dim_cvec : int + Size of control vector + hxbar_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + screen : int + Verbosity flag + type_opt : int + Type of minimizer for 3DVar + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + on exit: PE-local forecast state + Array shape: (dim_p) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.zeros((dim_p), dtype=np.float64, order="F") + cdef double [::1] state_p = state_p_np + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + with nogil: + c__pdaf3dvar_analysis_cvt(&step, &dim_p, &dim_obs_p, &dim_cvec, + &state_p[0], &hxbar_p[0], &obs_p[0], + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, &screen, + &type_opt, &debug, &flag) + + return state_p_np, flag + + +def lestkf_init(int subtype, int [::1] param_int, int dim_pint, + double [::1] param_real, int dim_preal, int verbose, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + dim_pint : int + Number of integer parameters + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + dim_preal : int + Number of real parameters + verbose : int + Control screen output + outflag : int + Status flag + + Returns + ------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + ensemblefilter : bint + Is the chosen filter ensemble-based? + fixedbasis : bint + Does the filter run with fixed error-space basis? + outflag : int + Status flag + """ + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_int_np = np.asarray(param_int, dtype=np.intc, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_real_np = np.asarray(param_real, dtype=np.float64, order="F") + cdef bint ensemblefilter + cdef bint fixedbasis + with nogil: + c__pdaf_lestkf_init(&subtype, ¶m_int[0], &dim_pint, + ¶m_real[0], &dim_preal, &ensemblefilter, + &fixedbasis, &verbose, &outflag) + + return subtype, param_int_np, param_real_np, ensemblefilter, fixedbasis, outflag + + +def lestkf_alloc(int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + with nogil: + c__pdaf_lestkf_alloc(&outflag) + + return outflag + + +def lestkf_config(int subtype, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + verbose : int + Control screen output + + Returns + ------- + subtype : int + Sub-type of filter + """ + with nogil: + c__pdaf_lestkf_config(&subtype, &verbose) + + return subtype + + +def lestkf_set_iparam(int id, int value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : int + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_lestkf_set_iparam(&id, &value, &flag) + + return flag + + +def lestkf_set_rparam(int id, double value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : double + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_lestkf_set_rparam(&id, &value, &flag) + + return flag + + +def lestkf_options(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdaf_lestkf_options() + + + +def lestkf_memtime(int printtype): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + printtype : int + Type of screen output: + + Returns + ------- + """ + with nogil: + c__pdaf_lestkf_memtime(&printtype) + + + +def seik_ana(int step, int dim_p, int dim_obs_p, int dim_ens, + int rank, double [::1] state_p, double [::1,:] uinv, + double [::1,:] ens_p, double [::1,:] hl_p, double [::1] hxbar_p, + double [::1] obs_p, double forget, py__prodrinva_pdaf, int debug, + int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_obs_p : int + PE-local dimension of observation vector + dim_ens : int + Size of ensemble + rank : int + Rank of initial covariance matrix + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of eigenvalue matrix U + Array shape: (rank, rank) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hl_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble (perturbations) + Array shape: (dim_obs_p, dim_ens) + hxbar_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + forget : double + Forgetting factor + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of eigenvalue matrix U + Array shape: (rank, rank) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hl_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble (perturbations) + Array shape: (dim_obs_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] uinv_np = np.asarray(uinv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hl_p_np = np.asarray(hl_p, dtype=np.float64, order="F") + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + with nogil: + c__pdaf_seik_ana(&step, &dim_p, &dim_obs_p, &dim_ens, &rank, + &state_p[0], &uinv[0,0], &ens_p[0,0], &hl_p[0,0], + &hxbar_p[0], &obs_p[0], &forget, + pdaf_cb.c__prodrinva_pdaf, &debug, &flag) + + return state_p_np, uinv_np, ens_p_np, hl_p_np, flag + + +def seik_resample(int subtype, int dim_p, int dim_ens, int rank, + double [::1,:] uinv, double [::1] state_p, double [::1,:] enst_p, + int type_sqrt, int type_trans, int nm1vsn, int screen, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Filter subtype + dim_p : int + PE-local state dimension + dim_ens : int + Size of ensemble + rank : int + Rank of initial covariance matrix + uinv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (rank, rank) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + enst_p : ndarray[np.float64, ndim=2] + PE-local ensemble times T + Array shape: (dim_p, dim_ens) + type_sqrt : int + Type of square-root of A + type_trans : int + Type of ensemble transformation + nm1vsn : int + Flag which normalization of P ist used in SEIK + screen : int + Verbosity flag + flag : int + Status flag + + Returns + ------- + uinv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (rank, rank) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + enst_p : ndarray[np.float64, ndim=2] + PE-local ensemble times T + Array shape: (dim_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] uinv_np = np.asarray(uinv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] enst_p_np = np.asarray(enst_p, dtype=np.float64, order="F") + with nogil: + c__pdaf_seik_resample(&subtype, &dim_p, &dim_ens, &rank, + &uinv[0,0], &state_p[0], &enst_p[0,0], + &type_sqrt, &type_trans, &nm1vsn, &screen, &flag) + + return uinv_np, state_p_np, enst_p_np, flag + + +def lseik_ana(int domain_p, int step, int dim_l, int dim_obs_l, + int dim_ens, int rank, double [::1] state_l, double [::1,:] uinv_l, + double [::1,:] ens_l, double [::1,:] hl_l, double [::1] hxbar_l, + double [::1] obs_l, double forget, py__prodrinva_l_pdaf, int screen, + int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + step : int + Current time step + dim_l : int + State dimension on local analysis domain + dim_obs_l : int + Size of obs. vector on local ana. domain + dim_ens : int + Size of ensemble + rank : int + Rank of initial covariance matrix + state_l : ndarray[np.float64, ndim=1] + State on local analysis domain + Array shape: (dim_l) + uinv_l : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (rank, rank) + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + hl_l : ndarray[np.float64, ndim=2] + Local observed state ensemble (perturbation) + Array shape: (dim_obs_l, dim_ens) + hxbar_l : ndarray[np.float64, ndim=1] + Local observed ensemble mean + Array shape: (dim_obs_l) + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_l) + forget : double + Forgetting factor + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A for local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + screen : int + Verbosity flag + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_l : ndarray[np.float64, ndim=1] + State on local analysis domain + Array shape: (dim_l) + uinv_l : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (rank, rank) + hl_l : ndarray[np.float64, ndim=2] + Local observed state ensemble (perturbation) + Array shape: (dim_obs_l, dim_ens) + forget : double + Forgetting factor + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_l_np = np.asarray(state_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] uinv_l_np = np.asarray(uinv_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hl_l_np = np.asarray(hl_l, dtype=np.float64, order="F") + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + with nogil: + c__pdaf_lseik_ana(&domain_p, &step, &dim_l, &dim_obs_l, &dim_ens, + &rank, &state_l[0], &uinv_l[0,0], &ens_l[0,0], + &hl_l[0,0], &hxbar_l[0], &obs_l[0], &forget, + pdaf_cb.c__prodrinva_l_pdaf, &screen, &debug, &flag) + + return state_l_np, uinv_l_np, hl_l_np, forget, flag + + +def lseik_resample(int domain_p, int subtype, int dim_l, int dim_ens, + int rank, double [::1,:] uinv_l, double [::1] state_l, + double [::1,:] ens_l, double [::1,:] omegat_in, int type_sqrt, + int screen, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + subtype : int + Specification of filter subtype + dim_l : int + State dimension on local analysis domain + dim_ens : int + Size of ensemble + rank : int + Rank of initial covariance matrix + uinv_l : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (rank, rank) + state_l : ndarray[np.float64, ndim=1] + Local model state + Array shape: (dim_l) + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + omegat_in : ndarray[np.float64, ndim=2] + Matrix Omega + Array shape: (rank, dim_ens) + type_sqrt : int + Type of square-root of A + screen : int + Verbosity flag + flag : int + Status flag + + Returns + ------- + uinv_l : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (rank, rank) + state_l : ndarray[np.float64, ndim=1] + Local model state + Array shape: (dim_l) + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + omegat_in : ndarray[np.float64, ndim=2] + Matrix Omega + Array shape: (rank, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] uinv_l_np = np.asarray(uinv_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_l_np = np.asarray(state_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_l_np = np.asarray(ens_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] omegat_in_np = np.asarray(omegat_in, dtype=np.float64, order="F") + with nogil: + c__pdaf_lseik_resample(&domain_p, &subtype, &dim_l, &dim_ens, + &rank, &uinv_l[0,0], &state_l[0], + &ens_l[0,0], &omegat_in[0,0], &type_sqrt, + &screen, &flag) + + return uinv_l_np, state_l_np, ens_l_np, omegat_in_np, flag + + +def prepost(py__collect_state_pdaf, py__distribute_state_pdaf, + py__prepoststep_pdaf, py__next_observation_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf_prepost(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def enkf_update(int step, int dim_p, int dim_ens, double [::1] state_p, + double [::1,:] ens_p, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__add_obs_err_pdaf, py__init_obs_pdaf, py__init_obs_covar_pdaf, + py__prepoststep_pdaf, int screen, int subtype, int dim_lag, + double [::1,:,:] sens_p, int cnt_maxlag, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of state ensemble + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__add_obs_err_pdaf : Callable + Add observation error covariance matrix + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Dimension of observation vector + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_covar_pdaf : Callable + Initialize observation error covariance matrix + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs : int + Global size of observation vector + dim_obs_p : int + Size of process-local observation vector + obs_p : ndarray[np.float64, ndim=1] + Process-local vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + covar : ndarray[np.float64, ndim=2] + Observation error covariance matrix + Array shape: (dim_obs_p,dim_obs_p) + isdiag : bint + + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + screen : int + Verbosity flag + subtype : int + Specification of filter subtype + dim_lag : int + Number of past time instances for smoother + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count number of past time steps for smoothing + flag : int + Status flag + + Returns + ------- + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count number of past time steps for smoothing + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=3, mode="fortran", negative_indices=False, cast=False] sens_p_np = np.asarray(sens_p, dtype=np.float64, order="F") + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int dim_obs_p + with nogil: + c__pdafenkf_update(&step, &dim_p, &dim_obs_p, &dim_ens, + &state_p[0], &ens_p[0,0], + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, + pdaf_cb.c__prepoststep_pdaf, &screen, &subtype, + &dim_lag, &sens_p[0,0,0], &cnt_maxlag, &flag) + + return dim_obs_p, state_p_np, ens_p_np, sens_p_np, cnt_maxlag, flag + + +def init_parallel(int dim_ens, bint ensemblefilter, bint fixedbasis, + int comm_model, int in_comm_filter, int in_comm_couple, + int in_n_modeltasks, int in_task_id, int screen, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_ens : int + Rank of covar matrix/ensemble size + ensemblefilter : bint + Is the filter ensemble-based? + fixedbasis : bint + Run with fixed error-space basis? + comm_model : int + Model communicator (not shared) + in_comm_filter : int + Filter communicator + in_comm_couple : int + Coupling communicator + in_n_modeltasks : int + Number of model tasks + in_task_id : int + Task ID of current PE + screen : int + Whether screen information is shown + flag : int + Status flag + + Returns + ------- + dim_ens : int + Rank of covar matrix/ensemble size + flag : int + Status flag + """ + with nogil: + c__pdaf_init_parallel(&dim_ens, &ensemblefilter, &fixedbasis, + &comm_model, &in_comm_filter, + &in_comm_couple, &in_n_modeltasks, + &in_task_id, &screen, &flag) + + return dim_ens, flag + + +def seik_init(int subtype, int [::1] param_int, int dim_pint, + double [::1] param_real, int dim_preal, int verbose, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + dim_pint : int + Number of integer parameters + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + dim_preal : int + Number of real parameters + verbose : int + Control screen output + outflag : int + Status flag + + Returns + ------- + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + ensemblefilter : bint + Is the chosen filter ensemble-based? + fixedbasis : bint + Does the filter run with fixed error-space basis? + outflag : int + Status flag + """ + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_int_np = np.asarray(param_int, dtype=np.intc, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_real_np = np.asarray(param_real, dtype=np.float64, order="F") + cdef bint ensemblefilter + cdef bint fixedbasis + with nogil: + c__pdaf_seik_init(&subtype, ¶m_int[0], &dim_pint, + ¶m_real[0], &dim_preal, &ensemblefilter, + &fixedbasis, &verbose, &outflag) + + return param_int_np, param_real_np, ensemblefilter, fixedbasis, outflag + + +def seik_alloc(int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + with nogil: + c__pdaf_seik_alloc(&outflag) + + return outflag + + +def seik_config(int subtype, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + verbose : int + Control screen output + + Returns + ------- + subtype : int + Sub-type of filter + """ + with nogil: + c__pdaf_seik_config(&subtype, &verbose) + + return subtype + + +def seik_set_iparam(int id, int value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : int + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_seik_set_iparam(&id, &value, &flag) + + return flag + + +def seik_set_rparam(int id, double value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : double + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_seik_set_rparam(&id, &value, &flag) + + return flag + + +def seik_options(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdaf_seik_options() + + + +def seik_memtime(int printtype): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + printtype : int + Type of screen output: + + Returns + ------- + """ + with nogil: + c__pdaf_seik_memtime(&printtype) + + + +def netf_update(int step, int dim_p, int dim_ens, double [::1] state_p, + double [::1,:] ainv, double [::1,:] ens_p, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__likelihood_pdaf, + py__prepoststep_pdaf, int screen, int subtype, int dim_lag, + double [::1,:,:] sens_p, int cnt_maxlag, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (dim_ens, dim_ens) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__likelihood_pdaf : Callable + Compute observation likelihood for an ensemble member + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + resid : ndarray[np.float64, ndim=1] + Input vector holding the residual + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + likely : double + Output value of the likelihood + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + screen : int + Verbosity flag + subtype : int + Filter subtype + dim_lag : int + Number of past time instances for smoother + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count number of past time steps for smoothing + flag : int + Status flag + + Returns + ------- + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (dim_ens, dim_ens) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count number of past time steps for smoothing + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_np = np.asarray(ainv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=3, mode="fortran", negative_indices=False, cast=False] sens_p_np = np.asarray(sens_p, dtype=np.float64, order="F") + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.likelihood_pdaf = py__likelihood_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int dim_obs_p + with nogil: + c__pdafnetf_update(&step, &dim_p, &dim_obs_p, &dim_ens, + &state_p[0], &ainv[0,0], &ens_p[0,0], + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__likelihood_pdaf, + pdaf_cb.c__prepoststep_pdaf, &screen, &subtype, + &dim_lag, &sens_p[0,0,0], &cnt_maxlag, &flag) + + return dim_obs_p, state_p_np, ainv_np, ens_p_np, sens_p_np, cnt_maxlag, flag + + +def seik_ana_newt(int step, int dim_p, int dim_obs_p, int dim_ens, + int rank, double [::1] state_p, double [::1,:] uinv, + double [::1,:] ens_p, double [::1,:] hl_p, double [::1] hxbar_p, + double [::1] obs_p, double forget, py__prodrinva_pdaf, int screen, + int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_obs_p : int + PE-local dimension of observation vector + dim_ens : int + Size of ensemble + rank : int + Rank of initial covariance matrix + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of eigenvalue matrix U + Array shape: (rank, rank) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hl_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble (perturbations) + Array shape: (dim_obs_p, dim_ens) + hxbar_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + forget : double + Forgetting factor + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + screen : int + Verbosity flag + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of eigenvalue matrix U + Array shape: (rank, rank) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hl_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble (perturbations) + Array shape: (dim_obs_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] uinv_np = np.asarray(uinv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hl_p_np = np.asarray(hl_p, dtype=np.float64, order="F") + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + with nogil: + c__pdaf_seik_ana_newt(&step, &dim_p, &dim_obs_p, &dim_ens, &rank, + &state_p[0], &uinv[0,0], &ens_p[0,0], + &hl_p[0,0], &hxbar_p[0], &obs_p[0], &forget, + pdaf_cb.c__prodrinva_pdaf, &screen, &debug, &flag) + + return state_p_np, uinv_np, ens_p_np, hl_p_np, flag + + +def seik_resample_newt(int subtype, int dim_p, int dim_ens, int rank, + double [::1,:] uinv, double [::1] state_p, double [::1,:] ens_p, + int type_sqrt, int type_trans, int nm1vsn, int screen, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Filter subtype + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + rank : int + Rank of initial covariance matrix + uinv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (rank, rank) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + type_sqrt : int + Type of square-root of A + type_trans : int + Type of ensemble transformation + nm1vsn : int + Flag which normalization of P ist used in SEIK + screen : int + Verbosity flag + flag : int + Status flag + + Returns + ------- + uinv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (rank, rank) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] uinv_np = np.asarray(uinv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + with nogil: + c__pdaf_seik_resample_newt(&subtype, &dim_p, &dim_ens, &rank, + &uinv[0,0], &state_p[0], &ens_p[0,0], + &type_sqrt, &type_trans, &nm1vsn, + &screen, &flag) + + return uinv_np, state_p_np, ens_p_np, flag + + +def lenkf_ana_rsm(int step, int dim_p, int dim_obs_p, int dim_obs, int dim_ens, + int rank_ana, double [::1] state_p, double [::1,:] ens_p, + double [::1,:] hx_p, double [::1] hxbar_p, double [::1] obs_p, + py__add_obs_err_pdaf, py__init_obs_covar_pdaf, py__localize_covar_pdaf, + int screen, int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_obs_p : int + PE-local dimension of observation vector + dim_obs: int + Global dimension of observation vector + dim_ens : int + Size of state ensemble + rank_ana : int + Rank to be considered for inversion of HPH + state_p : ndarray[np.float64, ndim=1] + PE-local ensemble mean state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hx_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble + Array shape: (dim_obs_p, dim_ens) + hxbar_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + py__add_obs_err_pdaf : Callable + Add observation error covariance matrix + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Dimension of observation vector + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + py__init_obs_covar_pdaf : Callable + Initialize observation error covariance matrix + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs : int + Global size of observation vector + dim_obs_p : int + Size of process-local observation vector + obs_p : ndarray[np.float64, ndim=1] + Process-local vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + covar : ndarray[np.float64, ndim=2] + Observation error covariance matrix + Array shape: (dim_obs_p,dim_obs_p) + isdiag : bint + + + py__localize_covar_pdaf : Callable + Apply localization to HP and HPH^T + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + dim_obs : int + number of observations + hp_p : ndarray[np.float64, ndim=2] + pe local part of matrix hp + Array shape: (dim_obs, dim_p) + hph : ndarray[np.float64, ndim=2] + matrix hph + Array shape: (dim_obs, dim_obs) + + Callback Returns + ---------------- + hp_p : ndarray[np.float64, ndim=2] + pe local part of matrix hp + Array shape: (dim_obs, dim_p) + hph : ndarray[np.float64, ndim=2] + matrix hph + Array shape: (dim_obs, dim_obs) + + screen : int + Verbosity flag + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + PE-local ensemble mean state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + pdaf_cb.localize_covar_pdaf = py__localize_covar_pdaf + with nogil: + c__pdaf_lenkf_ana_rsm(&step, &dim_p, &dim_obs_p, &dim_obs, &dim_ens, + &rank_ana, &state_p[0], &ens_p[0,0], + &hx_p[0,0], &hxbar_p[0], &obs_p[0], + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, + pdaf_cb.c__localize_covar_pdaf, &screen, + &debug, &flag) + + return state_p_np, ens_p_np, flag + + +def lestkf_ana(int domain_p, int step, int dim_l, int dim_obs_l, + int dim_ens, int rank, double [::1] state_l, double [::1,:] ainv_l, + double [::1,:] ens_l, double [::1,:] hl_l, double [::1] hxbar_l, + double [::1] obs_l, double [::1,:] omegat_in, double forget, + py__prodrinva_l_pdaf, int envar_mode, int type_sqrt, + double [::1,:] ta, int screen, int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + step : int + Current time step + dim_l : int + State dimension on local analysis domain + dim_obs_l : int + Size of obs. vector on local ana. domain + dim_ens : int + Size of ensemble + rank : int + Rank of initial covariance matrix + state_l : ndarray[np.float64, ndim=1] + state on local analysis domain + Array shape: (dim_l) + ainv_l : ndarray[np.float64, ndim=2] + Inverse of matrix U - temporary use only + Array shape: (rank, rank) + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + hl_l : ndarray[np.float64, ndim=2] + Local observed state ensemble (perturbation) + Array shape: (dim_obs_l, dim_ens) + hxbar_l : ndarray[np.float64, ndim=1] + Local observed ensemble mean + Array shape: (dim_obs_l) + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_l) + omegat_in : ndarray[np.float64, ndim=2] + Matrix Omega + Array shape: (rank, dim_ens) + forget : double + Forgetting factor + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A for local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + envar_mode : int + Flag whether routine is called from 3DVar for special functionality + type_sqrt : int + Type of square-root of A + ta : ndarray[np.float64, ndim=2] + Ensemble transformation matrix + Array shape: (dim_ens, dim_ens) + screen : int + Verbosity flag + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_l : ndarray[np.float64, ndim=1] + state on local analysis domain + Array shape: (dim_l) + ainv_l : ndarray[np.float64, ndim=2] + Inverse of matrix U - temporary use only + Array shape: (rank, rank) + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + hl_l : ndarray[np.float64, ndim=2] + Local observed state ensemble (perturbation) + Array shape: (dim_obs_l, dim_ens) + forget : double + Forgetting factor + ta : ndarray[np.float64, ndim=2] + Ensemble transformation matrix + Array shape: (dim_ens, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_l_np = np.asarray(state_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_l_np = np.asarray(ainv_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_l_np = np.asarray(ens_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hl_l_np = np.asarray(hl_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ta_np = np.asarray(ta, dtype=np.float64, order="F") + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + with nogil: + c__pdaf_lestkf_ana(&domain_p, &step, &dim_l, &dim_obs_l, &dim_ens, + &rank, &state_l[0], &ainv_l[0,0], &ens_l[0,0], + &hl_l[0,0], &hxbar_l[0], &obs_l[0], + &omegat_in[0,0], &forget, + pdaf_cb.c__prodrinva_l_pdaf, &envar_mode, + &type_sqrt, &ta[0,0], &screen, &debug, &flag) + + return state_l_np, ainv_l_np, ens_l_np, hl_l_np, forget, ta_np, flag + + +def lestkf_update(int step, int dim_p, int dim_ens, int rank, + double [::1] state_p, double [::1,:] ainv, double [::1,:] ens_p, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__init_obs_l_pdaf, py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, + py__l2g_state_pdaf, py__g2l_obs_pdaf, py__init_obsvar_pdaf, + py__init_obsvar_l_pdaf, py__prepoststep_pdaf, int screen, + int subtype, int envar_mode, int dim_lag, double [::1,:,:] sens_p, + int cnt_maxlag, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + rank : int + Rank of initial covariance matrix + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (rank, rank) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prodrinva_l_pdaf : Callable + Compute product of R^(-1) with HV + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from global state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + screen : int + Verbosity flag + subtype : int + Filter subtype + envar_mode : int + Flag whether routine is called from 3DVar for special functionality + dim_lag : int + Number of past time instances for smoother + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count number of past time steps for smoothing + flag : int + Status flag + + Returns + ------- + dim_obs_f : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (rank, rank) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count number of past time steps for smoothing + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_np = np.asarray(ainv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=3, mode="fortran", negative_indices=False, cast=False] sens_p_np = np.asarray(sens_p, dtype=np.float64, order="F") + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int dim_obs_f + with nogil: + c__pdaflestkf_update(&step, &dim_p, &dim_obs_f, &dim_ens, &rank, + &state_p[0], &ainv[0,0], &ens_p[0,0], + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, &screen, + &subtype, &envar_mode, &dim_lag, + &sens_p[0,0,0], &cnt_maxlag, &flag) + + return dim_obs_f, state_p_np, ainv_np, ens_p_np, sens_p_np, cnt_maxlag, flag + + +def lnetf_init(int subtype, int [::1] param_int, int dim_pint, + double [::1] param_real, int dim_preal, int verbose, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + dim_pint : int + Number of integer parameters + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + dim_preal : int + Number of real parameters + verbose : int + Control screen output + outflag : int + Status flag + + Returns + ------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + ensemblefilter : bint + Is the chosen filter ensemble-based? + fixedbasis : bint + Does the filter run with fixed error-space basis? + outflag : int + Status flag + """ + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_int_np = np.asarray(param_int, dtype=np.intc, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_real_np = np.asarray(param_real, dtype=np.float64, order="F") + cdef bint ensemblefilter + cdef bint fixedbasis + with nogil: + c__pdaf_lnetf_init(&subtype, ¶m_int[0], &dim_pint, + ¶m_real[0], &dim_preal, &ensemblefilter, + &fixedbasis, &verbose, &outflag) + + return subtype, param_int_np, param_real_np, ensemblefilter, fixedbasis, outflag + + +def lnetf_alloc(int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + with nogil: + c__pdaf_lnetf_alloc(&outflag) + + return outflag + + +def lnetf_config(int subtype, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + verbose : int + Control screen output + + Returns + ------- + subtype : int + Sub-type of filter + """ + with nogil: + c__pdaf_lnetf_config(&subtype, &verbose) + + return subtype + + +def lnetf_set_iparam(int id, int value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : int + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_lnetf_set_iparam(&id, &value, &flag) + + return flag + + +def lnetf_set_rparam(int id, double value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : double + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_lnetf_set_rparam(&id, &value, &flag) + + return flag + + +def lnetf_options(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdaf_lnetf_options() + + + +def lnetf_memtime(int printtype): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + printtype : int + Type of screen output: + + Returns + ------- + """ + with nogil: + c__pdaf_lnetf_memtime(&printtype) + + + +def enkf_init(int subtype, int [::1] param_int, int dim_pint, + double [::1] param_real, int dim_preal, int verbose, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + dim_pint : int + Number of integer parameters + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + dim_preal : int + Number of real parameters + verbose : int + Control screen output + outflag : int + Status flag + + Returns + ------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + ensemblefilter : bint + Is the chosen filter ensemble-based? + fixedbasis : bint + Does the filter run with fixed error-space basis? + outflag : int + Status flag + """ + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_int_np = np.asarray(param_int, dtype=np.intc, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_real_np = np.asarray(param_real, dtype=np.float64, order="F") + cdef bint ensemblefilter + cdef bint fixedbasis + with nogil: + c__pdaf_enkf_init(&subtype, ¶m_int[0], &dim_pint, + ¶m_real[0], &dim_preal, &ensemblefilter, + &fixedbasis, &verbose, &outflag) + + return subtype, param_int_np, param_real_np, ensemblefilter, fixedbasis, outflag + + +def enkf_alloc(int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + with nogil: + c__pdaf_enkf_alloc(&outflag) + + return outflag + + +def enkf_config(int subtype, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + verbose : int + Control screen output + + Returns + ------- + subtype : int + Sub-type of filter + """ + with nogil: + c__pdaf_enkf_config(&subtype, &verbose) + + return subtype + + +def enkf_set_iparam(int id, int value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : int + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_enkf_set_iparam(&id, &value, &flag) + + return flag + + +def enkf_set_rparam(int id, double value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : double + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_enkf_set_rparam(&id, &value, &flag) + + return flag + + +def enkf_options(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdaf_enkf_options() + + + +def enkf_memtime(int printtype): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + printtype : int + Type of screen output: + + Returns + ------- + """ + with nogil: + c__pdaf_enkf_memtime(&printtype) + + + +def enkf_gather_resid(int dim_obs, int dim_obs_p, int dim_ens, + double [::1,:] resid_p): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_obs : int + Global observation dimension + dim_obs_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + resid_p : ndarray[np.float64, ndim=2] + PE-local residual matrix + Array shape: (dim_obs_p, dim_ens) + + Returns + ------- + resid : ndarray[np.float64, ndim=2] + Global residual matrix + Array shape: (dim_obs, dim_ens) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] resid_np = np.zeros((dim_obs, dim_ens), dtype=np.float64, order="F") + cdef double [::1,:] resid = resid_np + with nogil: + c__pdaf_enkf_gather_resid(&dim_obs, &dim_obs_p, &dim_ens, + &resid_p[0,0], &resid[0,0]) + + return resid_np + + +def enkf_obs_ensemble(int step, int dim_obs_p, int dim_obs, + int dim_ens, double [::1] obs_p, py__init_obs_covar_pdaf, int screen, + int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_obs_p : int + Local dimension of current observation + dim_obs : int + PE-local dimension of observation vector + dim_ens : int + Size of ensemble + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + py__init_obs_covar_pdaf : Callable + Initialize observation error covariance matrix + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs : int + Global size of observation vector + dim_obs_p : int + Size of process-local observation vector + obs_p : ndarray[np.float64, ndim=1] + Process-local vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + covar : ndarray[np.float64, ndim=2] + Observation error covariance matrix + Array shape: (dim_obs_p,dim_obs_p) + isdiag : bint + + + screen : int + Verbosity flag + flag : int + Status flag + + Returns + ------- + obsens_p : ndarray[np.float64, ndim=2] + PE-local obs. ensemble + Array shape: (dim_obs_p,dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] obsens_p_np = np.zeros((dim_obs_p,dim_ens), dtype=np.float64, order="F") + cdef double [::1,:] obsens_p = obsens_p_np + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + with nogil: + c__pdaf_enkf_obs_ensemble(&step, &dim_obs_p, &dim_obs, &dim_ens, + &obsens_p[0,0], &obs_p[0], + pdaf_cb.c__init_obs_covar_pdaf, &screen, + &flag) + + return obsens_p_np, flag + + +def pf_update(int step, int dim_p, int dim_ens, double [::1] state_p, + double [::1,:] ainv, double [::1,:] ens_p, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__likelihood_pdaf, + py__prepoststep_pdaf, int screen, int subtype, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (dim_ens, dim_ens) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__likelihood_pdaf : Callable + Compute observation likelihood for an ensemble member + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + resid : ndarray[np.float64, ndim=1] + Input vector holding the residual + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + likely : double + Output value of the likelihood + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + screen : int + Verbosity flag + subtype : int + Filter subtype + flag : int + Status flag + + Returns + ------- + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (dim_ens, dim_ens) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_np = np.asarray(ainv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.likelihood_pdaf = py__likelihood_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int dim_obs_p + with nogil: + c__pdafpf_update(&step, &dim_p, &dim_obs_p, &dim_ens, &state_p[0], + &ainv[0,0], &ens_p[0,0], + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__likelihood_pdaf, + pdaf_cb.c__prepoststep_pdaf, &screen, &subtype, &flag) + + return dim_obs_p, state_p_np, ainv_np, ens_p_np, flag + + +def generate_rndmat(int dim, int mattype): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim : int + Size of matrix rndmat + mattype : int + Select type of random matrix: + + Returns + ------- + rndmat : ndarray[np.float64, ndim=2] + Matrix + Array shape: (dim, dim) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] rndmat_np = np.zeros((dim, dim), dtype=np.float64, order="F") + cdef double [::1,:] rndmat = rndmat_np + with nogil: + c__pdaf_generate_rndmat(&dim, &rndmat[0,0], &mattype) + + return rndmat_np + + +def print_domain_stats(int n_domains_p): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + n_domains_p : int + Number of PE-local analysis domains + + Returns + ------- + """ + with nogil: + c__pdaf_print_domain_stats(&n_domains_p) + + + +def init_local_obsstats(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdaf_init_local_obsstats() + + + +def incr_local_obsstats(int dim_obs_l): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_obs_l : int + Number of locally assimilated observations + + Returns + ------- + """ + with nogil: + c__pdaf_incr_local_obsstats(&dim_obs_l) + + + +def print_local_obsstats(int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + screen : int + Verbosity flag + + Returns + ------- + n_domains_with_obs : int + + """ + cdef int n_domains_with_obs + with nogil: + c__pdaf_print_local_obsstats(&screen, &n_domains_with_obs) + + return n_domains_with_obs + + +def seik_matrixt(int dim, int dim_ens, double [::1,:] a): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim : int + dimension of states + dim_ens : int + Size of ensemble + a : ndarray[np.float64, ndim=2] + Input/output matrix + Array shape: (dim, dim_ens) + + Returns + ------- + a : ndarray[np.float64, ndim=2] + Input/output matrix + Array shape: (dim, dim_ens) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] a_np = np.asarray(a, dtype=np.float64, order="F") + with nogil: + c__pdaf_seik_matrixt(&dim, &dim_ens, &a[0,0]) + + return a_np + + +def seik_ttimesa(int rank, int dim_col, double [::1,:] a): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + rank : int + Rank of initial covariance matrix + dim_col : int + Number of columns in A and B + a : ndarray[np.float64, ndim=2] + Input matrix + Array shape: (rank, dim_col) + + Returns + ------- + b : ndarray[np.float64, ndim=2] + Output matrix (TA) + Array shape: (rank+1, dim_col) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] b_np = np.zeros((rank+1, dim_col), dtype=np.float64, order="F") + cdef double [::1,:] b = b_np + with nogil: + c__pdaf_seik_ttimesa(&rank, &dim_col, &a[0,0], &b[0,0]) + + return b_np + + +def seik_omega(int rank, double [::1,:] omega, int omegatype, int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + rank : int + Approximated rank of covar matrix + omega : ndarray[np.float64, ndim=2] + Matrix Omega + Array shape: (rank+1, rank) + omegatype : int + Select type of Omega: + screen : int + Verbosity flag + + Returns + ------- + omega : ndarray[np.float64, ndim=2] + Matrix Omega + Array shape: (rank+1, rank) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] omega_np = np.asarray(omega, dtype=np.float64, order="F") + with nogil: + c__pdaf_seik_omega(&rank, &omega[0,0], &omegatype, &screen) + + return omega_np + + +def seik_uinv(int rank, double [::1,:] uinv): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + rank : int + Rank of initial covariance matrix + uinv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (rank, rank) + + Returns + ------- + uinv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (rank, rank) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] uinv_np = np.asarray(uinv, dtype=np.float64, order="F") + with nogil: + c__pdaf_seik_uinv(&rank, &uinv[0,0]) + + return uinv_np + + +def ens_omega(int [::1] seed, int r, int dim_ens, double [::1,:] omega, + double norm, int otype, int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + seed : ndarray[np.intc, ndim=1] + Seed for random number generation + Array shape: (4) + r : int + Approximated rank of covar matrix + dim_ens : int + Ensemble size + omega : ndarray[np.float64, ndim=2] + Random matrix + Array shape: (dim_ens,r) + norm : double + Norm for ensemble transformation + otype : int + Type of Omega: + screen : int + Control verbosity + + Returns + ------- + omega : ndarray[np.float64, ndim=2] + Random matrix + Array shape: (dim_ens,r) + norm : double + Norm for ensemble transformation + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] omega_np = np.asarray(omega, dtype=np.float64, order="F") + with nogil: + c__pdaf_ens_omega(&seed[0], &r, &dim_ens, &omega[0,0], &norm, + &otype, &screen) + + return omega_np, norm + + +def estkf_omegaa(int rank, int dim_col, double [::1,:] a): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + rank : int + Rank of initial covariance matrix + dim_col : int + Number of columns in A and B + a : ndarray[np.float64, ndim=2] + Input matrix + Array shape: (rank, dim_col) + + Returns + ------- + b : ndarray[np.float64, ndim=2] + Output matrix (TA) + Array shape: (rank+1, dim_col) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] b_np = np.zeros((rank+1, dim_col), dtype=np.float64, order="F") + cdef double [::1,:] b = b_np + with nogil: + c__pdaf_estkf_omegaa(&rank, &dim_col, &a[0,0], &b[0,0]) + + return b_np + + +def estkf_aomega(int dim, int dim_ens, double [::1,:] a): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim : int + dimension of states + dim_ens : int + Size of ensemble + a : ndarray[np.float64, ndim=2] + Input/output matrix + Array shape: (dim, dim_ens) + + Returns + ------- + a : ndarray[np.float64, ndim=2] + Input/output matrix + Array shape: (dim, dim_ens) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] a_np = np.asarray(a, dtype=np.float64, order="F") + with nogil: + c__pdaf_estkf_aomega(&dim, &dim_ens, &a[0,0]) + + return a_np + + +def subtract_rowmean(int dim, int dim_ens, double [::1,:] a): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim : int + dimension of states + dim_ens : int + Size of ensemble + a : ndarray[np.float64, ndim=2] + Input/output matrix + Array shape: (dim, dim_ens) + + Returns + ------- + a : ndarray[np.float64, ndim=2] + Input/output matrix + Array shape: (dim, dim_ens) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] a_np = np.asarray(a, dtype=np.float64, order="F") + with nogil: + c__pdaf_subtract_rowmean(&dim, &dim_ens, &a[0,0]) + + return a_np + + +def subtract_colmean(int dim_ens, int dim, double [::1,:] a): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_ens : int + Rank of initial covariance matrix + dim : int + Number of columns in A and B + a : ndarray[np.float64, ndim=2] + Input/output matrix + Array shape: (dim_ens, dim) + + Returns + ------- + a : ndarray[np.float64, ndim=2] + Input/output matrix + Array shape: (dim_ens, dim) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] a_np = np.asarray(a, dtype=np.float64, order="F") + with nogil: + c__pdaf_subtract_colmean(&dim_ens, &dim, &a[0,0]) + + return a_np + + +def add_particle_noise(int dim_p, int dim_ens, double [::1] state_p, + double [::1,:] ens_p, int type_noise, double noise_amp, int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_p : int + State dimension + dim_ens : int + Number of particles + state_p : ndarray[np.float64, ndim=1] + State vector (not filled) + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + Ensemble array + Array shape: (dim_p, dim_ens) + type_noise : int + Type of noise + noise_amp : double + Noise amplitude + screen : int + Verbosity flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + State vector (not filled) + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + Ensemble array + Array shape: (dim_p, dim_ens) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + with nogil: + c__pdaf_add_particle_noise(&dim_p, &dim_ens, &state_p[0], + &ens_p[0,0], &type_noise, &noise_amp, + &screen) + + return state_p_np, ens_p_np + + +def inflate_weights(int screen, int dim_ens, double alpha, + double [::1] weights): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + screen : int + verbosity flag + dim_ens : int + Ensemble size + alpha : double + Minimum limit of n_eff / N + weights : ndarray[np.float64, ndim=1] + weights (before and after inflation) + Array shape: (dim_ens) + + Returns + ------- + weights : ndarray[np.float64, ndim=1] + weights (before and after inflation) + Array shape: (dim_ens) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] weights_np = np.asarray(weights, dtype=np.float64, order="F") + with nogil: + c__pdaf_inflate_weights(&screen, &dim_ens, &alpha, &weights[0]) + + return weights_np + + +def inflate_ens(int dim, int dim_ens, double [::1] meanstate, + double [::1,:] ens, double forget, bint do_ensmean): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim : int + dimension of states + dim_ens : int + Size of ensemble + meanstate : ndarray[np.float64, ndim=1] + state vector to hold ensemble mean + Array shape: (dim) + ens : ndarray[np.float64, ndim=2] + Input/output ensemble matrix + Array shape: (dim, dim_ens) + forget : double + Forgetting factor + do_ensmean : bint + Whether to compute the ensemble mean state + + Returns + ------- + meanstate : ndarray[np.float64, ndim=1] + state vector to hold ensemble mean + Array shape: (dim) + ens : ndarray[np.float64, ndim=2] + Input/output ensemble matrix + Array shape: (dim, dim_ens) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] meanstate_np = np.asarray(meanstate, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_np = np.asarray(ens, dtype=np.float64, order="F") + with nogil: + c__pdaf_inflate_ens(&dim, &dim_ens, &meanstate[0], &ens[0,0], + &forget, &do_ensmean) + + return meanstate_np, ens_np + + +def alloc(int dim_p, int dim_ens, int dim_ens_task, int dim_es, + int statetask, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_p : int + Size of state vector + dim_ens : int + Ensemble size + dim_ens_task : int + Ensemble size handled by a model task + dim_es : int + Dimension of error space (size of Ainv) + statetask : int + Task ID forecasting a single state + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + with nogil: + c__pdaf_alloc(&dim_p, &dim_ens, &dim_ens_task, &dim_es, + &statetask, &outflag) + + return outflag + +def alloc_sens(int dim_p, int dim_ens, int dim_lag, int outflag): + """Allocate PDAF smoother array + + Parameters + ---------- + dim_p : int + Dimension of PE-local state vector + dim_ens: int + Ensemble size + dim_lag: int + Smoothing lag + outflag : int + Status flag + + Returns + ------- + outflag: int + Status flag + """ + with nogil: + c__pdaf_alloc_sens(&dim_p, &dim_ens, &dim_lag, &outflag) + return outflag + +def alloc_bias(int dim_bias_p, int outflag): + """Allocate PDAF bias array + + Parameters + ---------- + dim_bias_p : int + Dimension of PE-local bias vector + outflag : int + Status flag + + Returns + ------- + outflag: int + Status flag + """ + with nogil: + c__pdaf_alloc_bias(&dim_bias_p, &outflag) + return outflag + +def smoothing(int dim_p, int dim_ens, int dim_lag, double [::1,:] ainv, + double [::1,:,:] sens_p, int cnt_maxlag, double forget, int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + dim_lag : int + Number of past time instances for smoother + ainv : ndarray[np.float64, ndim=2] + Weight matrix for ensemble transformation + Array shape: (dim_ens, dim_ens) + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count available number of time steps for smoothing + forget : double + Forgetting factor + screen : int + Verbosity flag + + Returns + ------- + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count available number of time steps for smoothing + """ + cdef cnp.ndarray[cnp.float64_t, ndim=3, mode="fortran", negative_indices=False, cast=False] sens_p_np = np.asarray(sens_p, dtype=np.float64, order="F") + with nogil: + c__pdaf_smoothing(&dim_p, &dim_ens, &dim_lag, &ainv[0,0], + &sens_p[0,0,0], &cnt_maxlag, &forget, &screen) + + return sens_p_np, cnt_maxlag + + +def smoothing_local(int domain_p, int step, int dim_p, int dim_l, + int dim_ens, int dim_lag, double [::1,:] ainv, double [::1,:] ens_l, + double [::1,:,:] sens_p, int cnt_maxlag, py__g2l_state_pdaf, + py__l2g_state_pdaf, double forget, int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_l : int + State dimension on local analysis domain + dim_ens : int + Size of ensemble + dim_lag : int + Number of past time instances for smoother + ainv : ndarray[np.float64, ndim=2] + Weight matrix for ensemble transformation + Array shape: (dim_ens, dim_ens) + ens_l : ndarray[np.float64, ndim=2] + local past ensemble (temporary) + Array shape: (dim_l, dim_ens) + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count available number of time steps for smoothing + py__g2l_state_pdaf : Callable + Get state on local ana. domain from global state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + forget : double + Forgetting factor + screen : int + Verbosity flag + + Returns + ------- + ens_l : ndarray[np.float64, ndim=2] + local past ensemble (temporary) + Array shape: (dim_l, dim_ens) + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count available number of time steps for smoothing + """ + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_l_np = np.asarray(ens_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=3, mode="fortran", negative_indices=False, cast=False] sens_p_np = np.asarray(sens_p, dtype=np.float64, order="F") + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + with nogil: + c__pdaf_smoothing_local(&domain_p, &step, &dim_p, &dim_l, &dim_ens, + &dim_lag, &ainv[0,0], &ens_l[0,0], + &sens_p[0,0,0], &cnt_maxlag, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, &forget, &screen) + + return ens_l_np, sens_p_np, cnt_maxlag + + +def smoother_shift(int dim_p, int dim_ens, int dim_lag, + double [::1,:,:] ens_p, double [::1,:,:] sens_p, int cnt_maxlag, + int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + dim_lag : int + Number of past time instances for smoother + ens_p : ndarray[np.float64, ndim=3] + PE-local state ensemble + Array shape: (dim_p, dim_ens, 1) + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count available number of time steps for smoothing + screen : int + Verbosity flag + + Returns + ------- + ens_p : ndarray[np.float64, ndim=3] + PE-local state ensemble + Array shape: (dim_p, dim_ens, 1) + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count available number of time steps for smoothing + """ + cdef cnp.ndarray[cnp.float64_t, ndim=3, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=3, mode="fortran", negative_indices=False, cast=False] sens_p_np = np.asarray(sens_p, dtype=np.float64, order="F") + with nogil: + c__pdaf_smoother_shift(&dim_p, &dim_ens, &dim_lag, &ens_p[0,0,0], + &sens_p[0,0,0], &cnt_maxlag, &screen) + + return ens_p_np, sens_p_np, cnt_maxlag + + +def lknetf_update_sync(int step, int dim_p, int dim_ens, + double [::1] state_p, double [::1,:] ainv, double [::1,:] ens_p, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__init_obs_l_pdaf, py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, + py__l2g_state_pdaf, py__g2l_obs_pdaf, py__init_obsvar_pdaf, + py__init_obsvar_l_pdaf, py__likelihood_l_pdaf, py__prepoststep_pdaf, + int screen, int subtype, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (dim_ens, dim_ens) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prodrinva_l_pdaf : Callable + Compute product of R^(-1) with HV + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from global state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__likelihood_l_pdaf : Callable + Compute likelihood + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + screen : int + Verbosity flag + subtype : int + Filter subtype + flag : int + Status flag + + Returns + ------- + dim_obs_f : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (dim_ens, dim_ens) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_np = np.asarray(ainv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int dim_obs_f + with nogil: + c__pdaflknetf_update_sync(&step, &dim_p, &dim_obs_f, &dim_ens, + &state_p[0], &ainv[0,0], &ens_p[0,0], + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, &screen, + &subtype, &flag) + + return dim_obs_f, state_p_np, ainv_np, ens_p_np, flag + + +def etkf_ana(int step, int dim_p, int dim_obs_p, int dim_ens, + double [::1,:] ens_p, double [::1,:] hz_p, double [::1] hxbar_p, + double [::1] obs_p, double forget, py__prodrinva_pdaf, int screen, + int type_trans, int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_obs_p : int + PE-local dimension of observation vector + dim_ens : int + Size of ensemble + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hz_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble + Array shape: (dim_obs_p, dim_ens) + hxbar_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + forget : double + Forgetting factor + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + screen : int + Verbosity flag + type_trans : int + Type of ensemble transformation + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + on exit: PE-local forecast state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + on exit: weight matrix for ensemble transformation + Array shape: (dim_ens, dim_ens) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hz_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble + Array shape: (dim_obs_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.zeros((dim_p), dtype=np.float64, order="F") + cdef double [::1] state_p = state_p_np + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_np = np.zeros((dim_ens, dim_ens), dtype=np.float64, order="F") + cdef double [::1,:] ainv = ainv_np + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hz_p_np = np.asarray(hz_p, dtype=np.float64, order="F") + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + with nogil: + c__pdaf_etkf_ana(&step, &dim_p, &dim_obs_p, &dim_ens, &state_p[0], + &ainv[0,0], &ens_p[0,0], &hz_p[0,0], &hxbar_p[0], + &obs_p[0], &forget, pdaf_cb.c__prodrinva_pdaf, + &screen, &type_trans, &debug, &flag) + + return state_p_np, ainv_np, ens_p_np, hz_p_np, flag + + +def letkf_ana(int domain_p, int step, int dim_l, int dim_obs_l, + int dim_ens, double [::1] state_l, double [::1,:] ens_l, + double [::1,:] hz_l, double [::1] hxbar_l, double [::1] obs_l, + double [::1,:] rndmat, double forget, py__prodrinva_l_pdaf, + int type_trans, int screen, int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + step : int + Current time step + dim_l : int + State dimension on local analysis domain + dim_obs_l : int + Size of obs. vector on local ana. domain + dim_ens : int + Size of ensemble + state_l : ndarray[np.float64, ndim=1] + Local forecast state + Array shape: (dim_l) + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + hz_l : ndarray[np.float64, ndim=2] + Local observed state ensemble (perturbation) + Array shape: (dim_obs_l, dim_ens) + hxbar_l : ndarray[np.float64, ndim=1] + Local observed ensemble mean + Array shape: (dim_obs_l) + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_l) + rndmat : ndarray[np.float64, ndim=2] + Global random rotation matrix + Array shape: (dim_ens, dim_ens) + forget : double + Forgetting factor + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A for local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + type_trans : int + Type of ensemble transformation + screen : int + Verbosity flag + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_l : ndarray[np.float64, ndim=1] + Local forecast state + Array shape: (dim_l) + ainv_l : ndarray[np.float64, ndim=2] + on exit: local weight matrix for ensemble transformation + Array shape: (dim_ens, dim_ens) + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + hz_l : ndarray[np.float64, ndim=2] + Local observed state ensemble (perturbation) + Array shape: (dim_obs_l, dim_ens) + rndmat : ndarray[np.float64, ndim=2] + Global random rotation matrix + Array shape: (dim_ens, dim_ens) + forget : double + Forgetting factor + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_l_np = np.asarray(state_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_l_np = np.zeros((dim_ens, dim_ens), dtype=np.float64, order="F") + cdef double [::1,:] ainv_l = ainv_l_np + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_l_np = np.asarray(ens_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hz_l_np = np.asarray(hz_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] rndmat_np = np.asarray(rndmat, dtype=np.float64, order="F") + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + with nogil: + c__pdaf_letkf_ana(&domain_p, &step, &dim_l, &dim_obs_l, &dim_ens, + &state_l[0], &ainv_l[0,0], &ens_l[0,0], + &hz_l[0,0], &hxbar_l[0], &obs_l[0], &rndmat[0,0], + &forget, pdaf_cb.c__prodrinva_l_pdaf, + &type_trans, &screen, &debug, &flag) + + return state_l_np, ainv_l_np, ens_l_np, hz_l_np, rndmat_np, forget, flag + + +def letkf_init(int subtype, int [::1] param_int, int dim_pint, + double [::1] param_real, int dim_preal, int verbose, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + dim_pint : int + Number of integer parameters + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + dim_preal : int + Number of real parameters + verbose : int + Control screen output + outflag : int + Status flag + + Returns + ------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + ensemblefilter : bint + Is the chosen filter ensemble-based? + fixedbasis : bint + Does the filter run with fixed error-space basis? + outflag : int + Status flag + """ + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_int_np = np.asarray(param_int, dtype=np.intc, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_real_np = np.asarray(param_real, dtype=np.float64, order="F") + cdef bint ensemblefilter + cdef bint fixedbasis + with nogil: + c__pdaf_letkf_init(&subtype, ¶m_int[0], &dim_pint, + ¶m_real[0], &dim_preal, &ensemblefilter, + &fixedbasis, &verbose, &outflag) + + return subtype, param_int_np, param_real_np, ensemblefilter, fixedbasis, outflag + + +def letkf_alloc(int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + with nogil: + c__pdaf_letkf_alloc(&outflag) + + return outflag + + +def letkf_config(int subtype, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + verbose : int + Control screen output + + Returns + ------- + subtype : int + Sub-type of filter + """ + with nogil: + c__pdaf_letkf_config(&subtype, &verbose) + + return subtype + + +def letkf_set_iparam(int id, int value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : int + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_letkf_set_iparam(&id, &value, &flag) + + return flag + + +def letkf_set_rparam(int id, double value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : double + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_letkf_set_rparam(&id, &value, &flag) + + return flag + + +def letkf_options(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdaf_letkf_options() + + + +def letkf_memtime(int printtype): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + printtype : int + Type of screen output: + + Returns + ------- + """ + with nogil: + c__pdaf_letkf_memtime(&printtype) + + + +def estkf_ana(int step, int dim_p, int dim_obs_p, int dim_ens, + int rank, double [::1] state_p, double [::1,:] ainv, + double [::1,:] ens_p, double [::1,:] hl_p, double [::1] hxbar_p, + double [::1] obs_p, double forget, py__prodrinva_pdaf, int screen, + int envar_mode, int type_sqrt, int type_trans, double [::1,:] ta, + int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_obs_p : int + PE-local dimension of observation vector + dim_ens : int + Size of ensemble + rank : int + Rank of initial covariance matrix + state_p : ndarray[np.float64, ndim=1] + on exit: PE-local forecast mean state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix A - temporary use only + Array shape: (rank, rank) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hl_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble + Array shape: (dim_obs_p, dim_ens) + hxbar_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + forget : double + Forgetting factor + py__prodrinva_pdaf : Callable + Provide product R^-1 with some matrix + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + screen : int + Verbosity flag + envar_mode : int + Flag whether routine is called from 3DVar for special functionality + type_sqrt : int + Type of square-root of A + type_trans : int + Type of ensemble transformation + ta : ndarray[np.float64, ndim=2] + Ensemble transformation matrix + Array shape: (dim_ens, dim_ens) + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + on exit: PE-local forecast mean state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix A - temporary use only + Array shape: (rank, rank) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hl_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble + Array shape: (dim_obs_p, dim_ens) + ta : ndarray[np.float64, ndim=2] + Ensemble transformation matrix + Array shape: (dim_ens, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_np = np.asarray(ainv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hl_p_np = np.asarray(hl_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ta_np = np.asarray(ta, dtype=np.float64, order="F") + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + with nogil: + c__pdaf_estkf_ana(&step, &dim_p, &dim_obs_p, &dim_ens, &rank, + &state_p[0], &ainv[0,0], &ens_p[0,0], &hl_p[0,0], + &hxbar_p[0], &obs_p[0], &forget, + pdaf_cb.c__prodrinva_pdaf, &screen, &envar_mode, + &type_sqrt, &type_trans, &ta[0,0], &debug, &flag) + + return dim_obs_p, state_p_np, ainv_np, ens_p_np, hl_p_np, ta_np, flag + + +def ensrf_ana(int step, int dim_p, int dim_obs_p, int dim_ens, + double [::1] state_p, double [::1,:] ens_p, double [::1,:] hx_p, + double [::1] hxbar_p, double [::1] obs_p, double [::1] var_obs_p, + py__localize_covar_serial_pdaf, int screen, int debug): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_obs_p : int + PE-local dimension of observation vector + dim_ens : int + Size of state ensemble + state_p : ndarray[np.float64, ndim=1] + PE-local ensemble mean state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hx_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble + Array shape: (dim_obs_p, dim_ens) + hxbar_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + var_obs_p : ndarray[np.float64, ndim=1] + PE-local vector of observation eror variances + Array shape: (dim_obs_p) + py__localize_covar_serial_pdaf : Callable + Apply localization for single-observation vectors + + Callback Parameters + ------------------- + iobs : int + Index of current observation + dim_p : int + Process-local state dimension + dim_obs : int + Number of observations + hp_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HP for observation iobs + Array shape: (dim_p) + hxy_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HX(HX_all) for full observations + Array shape: (dim_obs) + + Callback Returns + ---------------- + hp_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HP for observation iobs + Array shape: (dim_p) + hxy_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HX(HX_all) for full observations + Array shape: (dim_obs) + + screen : int + Verbosity flag + debug : int + Flag for writing debug output + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + PE-local ensemble mean state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hx_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble + Array shape: (dim_obs_p, dim_ens) + hxbar_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hx_p_np = np.asarray(hx_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] hxbar_p_np = np.asarray(hxbar_p, dtype=np.float64, order="F") + pdaf_cb.localize_covar_serial_pdaf = py__localize_covar_serial_pdaf + with nogil: + c__pdaf_ensrf_ana(&step, &dim_p, &dim_obs_p, &dim_ens, &state_p[0], + &ens_p[0,0], &hx_p[0,0], &hxbar_p[0], &obs_p[0], + &var_obs_p[0], + pdaf_cb.c__localize_covar_serial_pdaf, &screen, + &debug) + + return state_p_np, ens_p_np, hx_p_np, hxbar_p_np + + +def ensrf_ana_2step(int step, int dim_p, int dim_obs_p, int dim_ens, + double [::1] state_p, double [::1,:] ens_p, double [::1,:] hx_p, + double [::1] hxbar_p, double [::1] obs_p, double [::1] var_obs_p, + py__localize_covar_serial_pdaf, int screen, int debug): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_obs_p : int + PE-local dimension of observation vector + dim_ens : int + Size of state ensemble + state_p : ndarray[np.float64, ndim=1] + PE-local ensemble mean state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hx_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble + Array shape: (dim_obs_p, dim_ens) + hxbar_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + var_obs_p : ndarray[np.float64, ndim=1] + PE-local vector of observation eror variances + Array shape: (dim_obs_p) + py__localize_covar_serial_pdaf : Callable + Apply localization for single-observation vectors + + Callback Parameters + ------------------- + iobs : int + Index of current observation + dim_p : int + Process-local state dimension + dim_obs : int + Number of observations + hp_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HP for observation iobs + Array shape: (dim_p) + hxy_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HX(HX_all) for full observations + Array shape: (dim_obs) + + Callback Returns + ---------------- + hp_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HP for observation iobs + Array shape: (dim_p) + hxy_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HX(HX_all) for full observations + Array shape: (dim_obs) + + screen : int + Verbosity flag + debug : int + Flag for writing debug output + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + PE-local ensemble mean state + Array shape: (dim_p) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hx_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble + Array shape: (dim_obs_p, dim_ens) + hxbar_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hx_p_np = np.asarray(hx_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] hxbar_p_np = np.asarray(hxbar_p, dtype=np.float64, order="F") + pdaf_cb.localize_covar_serial_pdaf = py__localize_covar_serial_pdaf + with nogil: + c__pdaf_ensrf_ana_2step(&step, &dim_p, &dim_obs_p, &dim_ens, + &state_p[0], &ens_p[0,0], &hx_p[0,0], + &hxbar_p[0], &obs_p[0], &var_obs_p[0], + pdaf_cb.c__localize_covar_serial_pdaf, + &screen, &debug) + + return state_p_np, ens_p_np, hx_p_np, hxbar_p_np + + +def lnetf_update(int step, int dim_p, int dim_ens, + double [::1] state_p, double [::1,:] ainv, double [::1,:] ens_p, + py__obs_op_pdaf, py__init_dim_obs_pdaf, py__init_obs_pdaf, + py__init_obs_l_pdaf, py__likelihood_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, + py__l2g_state_pdaf, py__g2l_obs_pdaf, py__prepoststep_pdaf, + int screen, int subtype, int dim_lag, double [::1,:,:] sens_p, + int cnt_maxlag, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (dim_ens, dim_ens) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__likelihood_l_pdaf : Callable + Compute observation likelihood for an ensemble member + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from global state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + screen : int + Verbosity flag + subtype : int + Filter subtype + dim_lag : int + Status flag + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count number of past time steps for smoothing + flag : int + Status flag + + Returns + ------- + dim_obs_f : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Inverse of matrix U + Array shape: (dim_ens, dim_ens) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + dim_lag : int + Status flag + sens_p : ndarray[np.float64, ndim=3] + PE-local smoother ensemble + Array shape: (dim_p, dim_ens, dim_lag) + cnt_maxlag : int + Count number of past time steps for smoothing + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_np = np.asarray(ainv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=3, mode="fortran", negative_indices=False, cast=False] sens_p_np = np.asarray(sens_p, dtype=np.float64, order="F") + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int dim_obs_f + with nogil: + c__pdaflnetf_update(&step, &dim_p, &dim_obs_f, &dim_ens, + &state_p[0], &ainv[0,0], &ens_p[0,0], + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, &screen, &subtype, + &dim_lag, &sens_p[0,0,0], &cnt_maxlag, &flag) + + return dim_obs_f, state_p_np, ainv_np, ens_p_np, dim_lag, sens_p_np, cnt_maxlag, flag + + +def seik_ana_trans(int step, int dim_p, int dim_obs_p, int dim_ens, + int rank, double [::1] state_p, double [::1,:] uinv, + double [::1,:] ens_p, double [::1,:] hl_p, double [::1] hxbar_p, + double [::1] obs_p, double forget, py__prodrinva_pdaf, int screen, + int type_sqrt, int type_trans, int nm1vsn, int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_obs_p : int + PE-local dimension of observation vector + dim_ens : int + Size of ensemble + rank : int + Rank of initial covariance matrix + state_p : ndarray[np.float64, ndim=1] + PE-local forecast mean state + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of matrix U - temporary use only + Array shape: (rank, rank) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hl_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble (perturbations) + Array shape: (dim_obs_p, dim_ens) + hxbar_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + forget : double + Forgetting factor + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + screen : int + Verbosity flag + type_sqrt : int + Type of square-root of A + type_trans : int + Type of ensemble transformation + nm1vsn : int + Type of normalization in covariance matrix computation + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + PE-local forecast mean state + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of matrix U - temporary use only + Array shape: (rank, rank) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hl_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble (perturbations) + Array shape: (dim_obs_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] uinv_np = np.asarray(uinv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hl_p_np = np.asarray(hl_p, dtype=np.float64, order="F") + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + with nogil: + c__pdaf_seik_ana_trans(&step, &dim_p, &dim_obs_p, &dim_ens, &rank, + &state_p[0], &uinv[0,0], &ens_p[0,0], + &hl_p[0,0], &hxbar_p[0], &obs_p[0], &forget, + pdaf_cb.c__prodrinva_pdaf, &screen, + &type_sqrt, &type_trans, &nm1vsn, &debug, &flag) + + return state_p_np, uinv_np, ens_p_np, hl_p_np, flag + + +def hyb3dvar_update_estkf(int step, int dim_p, int dim_ens, + int dim_cvec, int dim_cvec_ens, double [::1] state_p, + double [::1,:] ainv, double [::1,:] ens_p, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__prodrinva_pdaf, + py__prepoststep_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__cvt_pdaf, py__cvt_adj_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__init_obsvar_pdaf, int screen, + int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + dim_cvec : int + Size of control vector (parameterized part) + dim_cvec_ens : int + Size of control vector (ensemble part) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Transform matrix + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A for 3DVAR analysis + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble var) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + screen : int + Verbosity flag + flag : int + Status flag + + Returns + ------- + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Transform matrix + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_np = np.asarray(ainv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + cdef int dim_obs_p + with nogil: + c__pdafhyb3dvar_update_estkf(&step, &dim_p, &dim_obs_p, &dim_ens, + &dim_cvec, &dim_cvec_ens, &state_p[0], + &ainv[0,0], &ens_p[0,0], + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_obsvar_pdaf, &screen, + &flag) + + return dim_obs_p, state_p_np, ainv_np, ens_p_np, flag + + +def hyb3dvar_update_lestkf(int step, int dim_p, int dim_ens, + int dim_cvec, int dim_cvec_ens, double [::1] state_p, + double [::1,:] ainv, double [::1,:] ens_p, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__prodrinva_pdaf, + py__prepoststep_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__cvt_pdaf, py__cvt_adj_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, + py__init_obs_f_pdaf, py__init_obs_l_pdaf, py__prodrinva_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__g2l_obs_pdaf, py__init_obsvar_pdaf, py__init_obsvar_l_pdaf, + int screen, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_ens : int + Size of ensemble + dim_cvec : int + Size of control vector (parameterized part) + dim_cvec_ens : int + Size of control vector (ensemble part) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Transform matrix for LESKTF + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A for 3DVAR analysis + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble var) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_f_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Size of the full observation vector + + Callback Returns + ---------------- + observation_f : ndarray[np.float64, ndim=1] + Full vector of observations + Array shape: (dim_obs_f) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + screen : int + Verbosity flag + flag : int + Status flag + + Returns + ------- + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + Transform matrix for LESKTF + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble matrix + Array shape: (dim_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_np = np.asarray(ainv, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.init_obs_f_pdaf = py__init_obs_f_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + cdef int dim_obs_p + with nogil: + c__pdafhyb3dvar_update_lestkf(&step, &dim_p, &dim_obs_p, &dim_ens, + &dim_cvec, &dim_cvec_ens, + &state_p[0], &ainv[0,0], &ens_p[0,0], + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__init_obs_f_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + &screen, &flag) + + return dim_obs_p, state_p_np, ainv_np, ens_p_np, flag + +def lestkf_ana_fixed(int domain_p, int step, int dim_l, int dim_obs_l, + int dim_ens, int rank, double [::1] state_l, double [::1,:] ainv_l, + double [::1,:] ens_l, double [::1,:] hl_l, double [::1] hxbar_l, + double [::1] obs_l, double forget, py__prodrinva_l_pdaf, + int type_sqrt, int screen, int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + step : int + Current time step + dim_l : int + State dimension on local analysis domain + dim_obs_l : int + Size of obs. vector on local ana. domain + dim_ens : int + Size of ensemble + rank : int + Rank of initial covariance matrix + state_l : ndarray[np.float64, ndim=1] + state on local analysis domain + Array shape: (dim_l) + ainv_l : ndarray[np.float64, ndim=2] + Inverse of matrix U - temporary use only + Array shape: (rank, rank) + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + hl_l : ndarray[np.float64, ndim=2] + Local observed state ensemble (perturbation) + Array shape: (dim_obs_l, dim_ens) + hxbar_l : ndarray[np.float64, ndim=1] + Local observed ensemble mean + Array shape: (dim_obs_l) + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_l) + forget : double + Forgetting factor + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A for local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + type_sqrt : int + Type of square-root of A + screen : int + Verbosity flag + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_l : ndarray[np.float64, ndim=1] + state on local analysis domain + Array shape: (dim_l) + ainv_l : ndarray[np.float64, ndim=2] + Inverse of matrix U - temporary use only + Array shape: (rank, rank) + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + hl_l : ndarray[np.float64, ndim=2] + Local observed state ensemble (perturbation) + Array shape: (dim_obs_l, dim_ens) + forget : double + Forgetting factor + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_l_np = np.asarray(state_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_l_np = np.asarray(ainv_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_l_np = np.asarray(ens_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hl_l_np = np.asarray(hl_l, dtype=np.float64, order="F") + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + with nogil: + c__pdaf_lestkf_ana_fixed(&domain_p, &step, &dim_l, &dim_obs_l, + &dim_ens, &rank, &state_l[0], + &ainv_l[0,0], &ens_l[0,0], &hl_l[0,0], + &hxbar_l[0], &obs_l[0], &forget, + pdaf_cb.c__prodrinva_l_pdaf, &type_sqrt, + &screen, &debug, &flag) + + return state_l_np, ainv_l_np, ens_l_np, hl_l_np, forget, flag + + +def genobs_init(int subtype, int [::1] param_int, int dim_pint, + double [::1] param_real, int dim_preal, int verbose, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + dim_pint : int + Number of integer parameters + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + dim_preal : int + Number of real parameters + verbose : int + Control screen output + outflag : int + Status flag + + Returns + ------- + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + ensemblefilter : bint + Is the chosen filter ensemble-based? + fixedbasis : bint + Does the filter run with fixed error-space basis? + outflag : int + Status flag + """ + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_int_np = np.asarray(param_int, dtype=np.intc, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_real_np = np.asarray(param_real, dtype=np.float64, order="F") + cdef bint ensemblefilter + cdef bint fixedbasis + with nogil: + c__pdaf_genobs_init(&subtype, ¶m_int[0], &dim_pint, + ¶m_real[0], &dim_preal, &ensemblefilter, + &fixedbasis, &verbose, &outflag) + + return param_int_np, param_real_np, ensemblefilter, fixedbasis, outflag + + +def genobs_alloc(int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + with nogil: + c__pdaf_genobs_alloc(&outflag) + + return outflag + + +def genobs_config(int subtype, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + subtype : int + Sub-type of filter + verbose : int + Control screen output + + Returns + ------- + subtype : int + Sub-type of filter + """ + with nogil: + c__pdaf_genobs_config(&subtype, &verbose) + + return subtype + + +def genobs_set_iparam(int id, int value): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + id : int + Index of parameter + value : int + Parameter value + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + cdef int flag + with nogil: + c__pdaf_genobs_set_iparam(&id, &value, &flag) + + return flag + + +def genobs_options(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdaf_genobs_options() + + + +def etkf_ana_t(int step, int dim_p, int dim_obs_p, int dim_ens, + double [::1,:] ens_p, double [::1,:] hz_p, double [::1] hxbar_p, + double [::1] obs_p, double forget, py__prodrinva_pdaf, int screen, + int type_trans, int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + step : int + Current time step + dim_p : int + PE-local dimension of model state + dim_obs_p : int + PE-local dimension of observation vector + dim_ens : int + Size of ensemble + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hz_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble + Array shape: (dim_obs_p, dim_ens) + hxbar_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + obs_p : ndarray[np.float64, ndim=1] + PE-local observation vector + Array shape: (dim_obs_p) + forget : double + Forgetting factor + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + screen : int + Verbosity flag + type_trans : int + Type of ensemble transformation + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + on exit: PE-local forecast state + Array shape: (dim_p) + ainv : ndarray[np.float64, ndim=2] + on exit: weight matrix for ensemble transformation + Array shape: (dim_ens, dim_ens) + ens_p : ndarray[np.float64, ndim=2] + PE-local state ensemble + Array shape: (dim_p, dim_ens) + hz_p : ndarray[np.float64, ndim=2] + PE-local observed ensemble + Array shape: (dim_obs_p, dim_ens) + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.zeros((dim_p), dtype=np.float64, order="F") + cdef double [::1] state_p = state_p_np + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_np = np.zeros((dim_ens, dim_ens), dtype=np.float64, order="F") + cdef double [::1,:] ainv = ainv_np + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_p_np = np.asarray(ens_p, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hz_p_np = np.asarray(hz_p, dtype=np.float64, order="F") + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + with nogil: + c__pdaf_etkf_ana_t(&step, &dim_p, &dim_obs_p, &dim_ens, + &state_p[0], &ainv[0,0], &ens_p[0,0], + &hz_p[0,0], &hxbar_p[0], &obs_p[0], &forget, + pdaf_cb.c__prodrinva_pdaf, &screen, &type_trans, + &debug, &flag) + + return state_p_np, ainv_np, ens_p_np, hz_p_np, flag + + +def letkf_ana_fixed(int domain_p, int step, int dim_l, int dim_obs_l, + int dim_ens, double [::1] state_l, double [::1,:] ens_l, + double [::1,:] hz_l, double [::1] hxbar_l, double [::1] obs_l, + double forget, py__prodrinva_l_pdaf, int screen, int debug, int flag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + domain_p : int + Current local analysis domain + step : int + Current time step + dim_l : int + State dimension on local analysis domain + dim_obs_l : int + Size of obs. vector on local ana. domain + dim_ens : int + Size of ensemble + state_l : ndarray[np.float64, ndim=1] + Local forecast state + Array shape: (dim_l) + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + hz_l : ndarray[np.float64, ndim=2] + Local observed state ensemble (perturbation) + Array shape: (dim_obs_l, dim_ens) + hxbar_l : ndarray[np.float64, ndim=1] + Local observed ensemble mean + Array shape: (dim_obs_l) + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_l) + forget : double + Forgetting factor + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A for local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + screen : int + Verbosity flag + debug : int + Flag for writing debug output + flag : int + Status flag + + Returns + ------- + state_l : ndarray[np.float64, ndim=1] + Local forecast state + Array shape: (dim_l) + ainv_l : ndarray[np.float64, ndim=2] + on exit: local weight matrix for ensemble transformation + Array shape: (dim_ens, dim_ens) + ens_l : ndarray[np.float64, ndim=2] + Local state ensemble + Array shape: (dim_l, dim_ens) + hz_l : ndarray[np.float64, ndim=2] + Local observed state ensemble (perturbation) + Array shape: (dim_obs_l, dim_ens) + forget : double + Forgetting factor + flag : int + Status flag + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_l_np = np.asarray(state_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ainv_l_np = np.zeros((dim_ens, dim_ens), dtype=np.float64, order="F") + cdef double [::1,:] ainv_l = ainv_l_np + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_l_np = np.asarray(ens_l, dtype=np.float64, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hz_l_np = np.asarray(hz_l, dtype=np.float64, order="F") + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + with nogil: + c__pdaf_letkf_ana_fixed(&domain_p, &step, &dim_l, &dim_obs_l, + &dim_ens, &state_l[0], &ainv_l[0,0], + &ens_l[0,0], &hz_l[0,0], &hxbar_l[0], + &obs_l[0], &forget, + pdaf_cb.c__prodrinva_l_pdaf, &screen, + &debug, &flag) + + return state_l_np, ainv_l_np, ens_l_np, hz_l_np, forget, flag + + diff --git a/pyPDAF/source/src/pyPDAF/PDAF/meson.build b/pyPDAF/source/src/pyPDAF/PDAF/meson.build new file mode 100644 index 0000000000000000000000000000000000000000..1ab5a5b008979477857ca17fb37e0590baa13d6d --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/meson.build @@ -0,0 +1,32 @@ + +pypdaf_sources = files('assim.pyx', + 'callback.pyx', + 'diag.pyx', + 'get.pyx', + 'iau_internal.pyx', + 'iau.pyx', + 'internal.pyx', + '_pdaf_c.pyx', + 'put.pyx', + 'setter.pyx', + ) + +foreach file :pypdaf_sources + cython_ext = python.extension_module( + fs.stem(file), + file, + link_with: pdafc_lib, + dependencies : [mpi, dep_py, blas_dep, fruntime_dep], + include_directories: include_directories([incdir_numpy]), + c_args: c_cython_args, + link_args: link_args, + cython_args : cython_args, + link_language: 'fortran', + subdir: 'pyPDAF' / 'PDAF' , + install: true, + ) +endforeach + +python.install_sources(['__init__.py', 'py.typed', 'diag.pyi', 'get.pyi', + 'iau.pyi', '_pdaf_c.pyi', 'setter.pyi', + 'assim.pyi'], subdir: 'pyPDAF/PDAF') \ No newline at end of file diff --git a/pyPDAF/source/src/pyPDAF/PDAF/put.pxd b/pyPDAF/source/src/pyPDAF/PDAF/put.pxd new file mode 100644 index 0000000000000000000000000000000000000000..d1d62944beb11747c87d3232ce52ecb454bf7e80 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/put.pxd @@ -0,0 +1,351 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t +cdef extern void c__pdaf_put_state_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_put_state_lenkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__localize_covar_pdaf)(int* , int* , double* , double* ), + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_put_state_lseik( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_put_state_en3dvar_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_f_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_put_state_lknetf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__prodrinva_hyb_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__likelihood_hyb_l_pdaf)(int* , int* , int* , double* , + double* , double* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_put_state_hyb3dvar_estkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_put_state_lnetf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_put_state_letkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_put_state_en3dvar_estkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_put_state_hyb3dvar_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_f_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_put_state_netf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__likelihood_pdaf)(int* , int* , double* , double* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_put_state_etkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_put_state_ensrf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obsvars_pdaf)(int* , int* , double* ), + void (*c__localize_covar_serial_pdaf)(int* , int* , int* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_put_state_enkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_put_state_seik( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_put_state_generate_obs( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obserr_f_pdaf)(int* , int* , double* , double* ), + void (*c__get_obs_f_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_put_state_pf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__likelihood_pdaf)(int* , int* , double* , double* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_put_state_3dvar( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_put_state_estkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf_put_state_prepost( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/PDAF/put.pyx b/pyPDAF/source/src/pyPDAF/PDAF/put.pyx new file mode 100644 index 0000000000000000000000000000000000000000..c08f0104c81f643cfd34fd9cf28ba06b1103ead9 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/put.pyx @@ -0,0 +1,7119 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + +try: + import mpi4py + mpi4py.rc.initialize = False +except ImportError: + pass + +# Global error handler +def global_except_hook(exctype, value, traceback): + from traceback import print_exception + try: + import mpi4py.MPI + + if mpi4py.MPI.Is_initialized(): + try: + sys.stderr.write('Uncaught exception was ''detected on rank {}.\n'.format( + mpi4py.MPI.COMM_WORLD.Get_rank())) + print_exception(exctype, value, traceback) + sys.stderr.write("\n") + sys.stderr.flush() + finally: + try: + mpi4py.MPI.COMM_WORLD.Abort(1) + except Exception as e: + sys.stderr.write('MPI Abort failed, this process will hang.\n') + sys.stderr.flush() + raise e + else: + sys.__excepthook__(exctype, value, traceback) + except ImportError: + sys.__excepthook__(exctype, value, traceback) + +sys.excepthook = global_except_hook + +def put_state_lestkf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__init_obs_l_pdaf, + py__prepoststep_pdaf, py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, + py__l2g_state_pdaf, py__g2l_obs_pdaf, py__init_obsvar_pdaf, + py__init_obsvar_l_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_put_state` + or :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`. + + PDAFlocal-OMI modules require fewer user-supplied functions + and improved efficiency. + + Local ESTKF (error space transform Kalman filter) [1]_ for a single DA step without OMI. + + Compared to :func:`pyPDAF.PDAF.assimilate_lestkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The LESTKF is a more efficient equivalent to the LETKF. + + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. py__init_obs_pdaf + (if global adaptive forgetting factor `type_forget=1` is used + in :func:`pyPDAF.PDAF.init`) + 7. py__init_obsvar_pdaf (if global adaptive + forgetting factor is used) + 8. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf (localise mean ensemble + in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting factor + `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_put_state` + and :func:`pyPDAF.PDAF.localomi_put_state_nondiagR` + + References + ---------- + .. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + cdef int outflag + with nogil: + c__pdaf_put_state_lestkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, &outflag) + + return outflag + + +def put_state_lenkf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__prepoststep_pdaf, + py__localize_covar_pdaf, py__add_obs_err_pdaf, py__init_obs_covar_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_put_state_lenkf` + or :func:`pyPDAF.PDAF.omi_put_state_lenkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Stochastic EnKF (ensemble Kalman filter) + with covariance localisation [1]_ + for a single DA step without OMI. + + Compared to :func:`pyPDAF.PDAF.assimilate_lenkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + This is the only scheme for covariance localisation in PDAF. + + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. py__localize_pdaf + 6. py__add_obs_err_pdaf + 7. py__init_obs_pdaf + 8. py__init_obscovar_pdaf + 9. py__obs_op_pdaf (repeated to reduce storage) + 10. core DA algorith + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_put_state_lenkf` + and :func:`pyPDAF.PDAF.omi_put_state_lenkf_nondiagR` + + References + ---------- + .. [1] Houtekamer, P. L., and H. L. Mitchell (1998): + Data Assimilation Using an Ensemble Kalman + Filter Technique. + Mon. Wea. Rev., 126, 796–811, + doi: 10.1175/1520-0493(1998)126<0796:DAUAEK>2.0.CO;2. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__localize_covar_pdaf : Callable + Apply localization to HP and HPH^T + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + dim_obs : int + number of observations + hp_p : ndarray[np.float64, ndim=2] + pe local part of matrix hp + Array shape: (dim_obs, dim_p) + hph : ndarray[np.float64, ndim=2] + matrix hph + Array shape: (dim_obs, dim_obs) + + Callback Returns + ---------------- + hp_p : ndarray[np.float64, ndim=2] + pe local part of matrix hp + Array shape: (dim_obs, dim_p) + hph : ndarray[np.float64, ndim=2] + matrix hph + Array shape: (dim_obs, dim_obs) + + py__add_obs_err_pdaf : Callable + Add obs error covariance R to HPH in EnKF + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Dimension of observation vector + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + py__init_obs_covar_pdaf : Callable + Initialize obs. error cov. matrix R in EnKF + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs : int + Global size of observation vector + dim_obs_p : int + Size of process-local observation vector + obs_p : ndarray[np.float64, ndim=1] + Process-local vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + covar : ndarray[np.float64, ndim=2] + Observation error covariance matrix + Array shape: (dim_obs_p,dim_obs_p) + isdiag : bint + + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.localize_covar_pdaf = py__localize_covar_pdaf + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + cdef int outflag + with nogil: + c__pdaf_put_state_lenkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__localize_covar_pdaf, + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, &outflag) + + return outflag + + +def put_state_lseik(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__init_obs_l_pdaf, + py__prepoststep_pdaf, py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, + py__l2g_state_pdaf, py__g2l_obs_pdaf, py__init_obsvar_pdaf, + py__init_obsvar_l_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_put_state` + or :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Local singular evolutive interpolated Kalman filter [1]_ + for a single DA step. + + Compared to :func:`pyPDAF.PDAF.assimilate_lseik`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. py__init_obs_pdaf + (if global adaptive forgetting factor `type_forget=1` + is used in :func:`pyPDAF.PDAF.init`) + 7. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 8. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf (localise mean ensemble + in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting factor + `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_put_state` + and :func:`pyPDAF.PDAF.localomi_put_state_nondiagR` + + References + ---------- + .. [1] Pham, D. T., Verron, J., & Roubaud, M. C. (1998). + A singular evolutive extended Kalman filter for data assimilation + in oceanography. Journal of Marine systems, 16(3-4), 323-340. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + cdef int outflag + with nogil: + c__pdaf_put_state_lseik(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, &outflag) + + return outflag + + +def put_state_en3dvar_lestkf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__prodrinva_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, + py__init_obs_f_pdaf, py__init_obs_l_pdaf, py__prodrinva_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__g2l_obs_pdaf, py__init_obsvar_pdaf, py__init_obsvar_l_pdaf, + py__prepoststep_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf` + or :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + 3DEnVar for a single DA step without post-processing, + distributing analysis, and setting next observation step, + where the ensemble anomaly is generated by LESTKF. + + Compared to :func:`pyPDAF.PDAF.assimilate_en3dvar_lestkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The background error covariance matrix is estimated by ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An LESTKF is used to generate ensemble perturbations. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. Starting the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core DA algorithm + 7. py__cvt_ens_pdaf + 8. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__init_obs_pdaf + (if global adaptive forgetting factor is used + `type_forget=1` in :func:`pyPDAF.PDAF.init`) + 5. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise mean ensemble in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting factor + `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf` + and :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble var) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_f_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Size of the full observation vector + + Callback Returns + ---------------- + observation_f : ndarray[np.float64, ndim=1] + Full vector of observations + Array shape: (dim_obs_f) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.init_obs_f_pdaf = py__init_obs_f_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf_put_state_en3dvar_lestkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__init_obs_f_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_lknetf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__init_obs_l_pdaf, + py__prepoststep_pdaf, py__prodrinva_l_pdaf, py__prodrinva_hyb_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__g2l_obs_pdaf, py__init_obsvar_pdaf, py__init_obsvar_l_pdaf, + py__likelihood_l_pdaf, py__likelihood_hyb_l_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_put_state` + or :func:`pyPDAF.PDAF.localomi_put_state_lknetf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + A hybridised LETKF and LNETF [1]_ for a single DA step. + + Compared to :func:`pyPDAF.PDAF.assimilate_lknetf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The LNETF computes the distribution up to + the second moment similar to Kalman filters but + using a nonlinear weighting similar to + particle filters. This leads to an equal weights + assumption for the prior ensemble. + The hybridisation with LETKF is expected to lead to + improved performance for + quasi-Gaussian problems. + The function should be called at each model step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf + (for each ensemble member) + 6. py__init_obs_pdaf + (if global adaptive forgetting factor `type_forget=1` + is used in :func:`pyPDAF.PDAF.init`) + 7. py__init_obsvar_pdaf (if global adaptive + forgetting factor is used) + 8. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise each ensemble member in observation space) + 5. py__init_obs_l_pdaf + 6. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting factor + `type_forget=2` is used) + 7. py__prodRinvA_pdaf + 8. py__likelihood_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + 9. py__obs_op_pdaf + (only called with `HKN` and `HNK` options called + for each ensemble member) + 10. py__likelihood_hyb_l_pda + 11. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting factor + `type_forget=2` is used) + 12. py__prodRinvA_hyb_l_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_put_state` + and :func:`pyPDAF.PDAF.localomi_put_state_lknetf_nondiagR` + + References + ---------- + .. [1] Nerger, L.. (2022) + Data assimilation for nonlinear systems with + a hybrid nonlinear Kalman ensemble transform filter. + Q J R Meteorol Soc, 620–640. doi:10.1002/qj.4221 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__prodrinva_hyb_l_pdaf : Callable + Provide product R^-1 A on local analysis domain with hybrid weight + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + dim_ens : int + Number of the columns in the matrix processes here. This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__likelihood_l_pdaf : Callable + Compute likelihood + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__likelihood_hyb_l_pdaf : Callable + Compute likelihood with hybrid weight + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.prodrinva_hyb_l_pdaf = py__prodrinva_hyb_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.likelihood_hyb_l_pdaf = py__likelihood_hyb_l_pdaf + cdef int outflag + with nogil: + c__pdaf_put_state_lknetf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__prodrinva_hyb_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__likelihood_hyb_l_pdaf, &outflag) + + return outflag + + +def put_state_hyb3dvar_estkf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__prodrinva_pdaf, py__cvt_pdaf, + py__cvt_adj_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__init_obsvar_pdaf, + py__prepoststep_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_estkf` + or :func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_estkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Hybrid 3DEnVar for a single DA step where + the background error covariance is hybridised by + a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + + Compared to :func:`pyPDAF.PDAF.assimilate_hyb3dvar_estkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + ESTKF in this implementation. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. the iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core 3DEnVar algorithm + 7. py__cvt_pdaf + 8. py__cvt_ens_pdaf + 9. Perform ESTKF: + 1. py__init_dim_obs_pdaf + 2. py__obs_op_pdaf + (for ensemble mean) + 3. py__init_obs_pdaf + 4. py__obs_op_pdaf + (for each ensemble member) + 5. py__init_obsvar_pdaf + (only relevant for adaptive + forgetting factor schemes) + 6. py__prodRinvA_pdaf + 7. core ESTKF algorithm + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_estkf` + and :func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_estkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble var) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf_put_state_hyb3dvar_estkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_lnetf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__init_obs_l_pdaf, + py__prepoststep_pdaf, py__likelihood_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, + py__l2g_state_pdaf, py__g2l_obs_pdaf): + """It is recommended to use :func:`pyPDAF.PDAF.localomi_put_state` + or :func:`pyPDAF.PDAF.localomi_put_state_lnetf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Local Nonlinear Ensemble Transform Filter (LNETF) [1]_ + for a single DA step. + + Compared to :func:`pyPDAF.PDAF.assimilate_lnetf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The nonlinear filter computes the distribution up to + the second moment similar to Kalman filters + but it uses a nonlinear weighting similar to + particle filters. This leads to an equal weights + assumption for the prior ensemble at each step. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__init_obs_l_pdaf + 5. py__g2l_obs_pdaf (localise each ensemble member + in observation space) + 6. py__likelihood_l_pdaf + 7. core DA algorithm + 8. py__l2g_state_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_put_state` + and :func:`pyPDAF.PDAF.localomi_put_state_lnetf_nondiagR` + + References + ---------- + .. [1] Tödter, J., and B. Ahrens, 2015: + A second-order exact ensemble square root filter + for nonlinear data assimilation. Mon. Wea. Rev., + 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__likelihood_l_pdaf : Callable + Compute observation likelihood for an ensemble member + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + cdef int outflag + with nogil: + c__pdaf_put_state_lnetf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, &outflag) + + return outflag + + +def put_state_letkf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__init_obs_l_pdaf, + py__prepoststep_pdaf, py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, + py__l2g_state_pdaf, py__g2l_obs_pdaf, py__init_obsvar_pdaf, + py__init_obsvar_l_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_put_state` + or :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`. + + PDAFlocal-OMI modules require fewer user-supplied + functions and improved efficiency. + + Local ensemble transform Kalman filter (LETKF) [1]_ + for a single DA step without OMI. + Implementation is based on [2]_. + + Compared to :func:`pyPDAF.PDAF.assimilate_letkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + Note that the LESTKF is a more efficient equivalent to the LETKF. + + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. py__init_obs_pdaf + (if global adaptive forgetting factor + `type_forget=1` is used + in :func:`pyPDAF.PDAF.init`) + 7. py__init_obsvar_pdaf (if global adaptive forgetting + factor is used) + 8. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf (localise mean ensemble + in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting factor + `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_put_state` + and :func:`pyPDAF.PDAF.localomi_put_state_nondiagR` + + References + ---------- + .. [1] Hunt, B. R., Kostelich, E. J., & Szunyogh, I. (2007). + Efficient data assimilation for spatiotemporal chaos: + A local ensemble transform Kalman filter. + Physica D: Nonlinear Phenomena, 230(1-2), 112-126. + .. [2] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + cdef int outflag + with nogil: + c__pdaf_put_state_letkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, &outflag) + + return outflag + + +def put_state_en3dvar_estkf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__prodrinva_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__init_obsvar_pdaf, py__prepoststep_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_put_state_en3dvar_estkf` + or :func:`pyPDAF.PDAF.omi_put_state_en3dvar_estkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + 3DEnVar for a single DA step. + + Compared to :func:`pyPDAF.PDAF.assimilate_en3dvar_estkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will not be + assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The background error covariance matrix is + estimated by an ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An ESTKF is used along with 3DEnVar to + generate ensemble perturbations. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core 3DEnVar algorithm + 7. py__cvt_ens_pdaf + 8. ESTKF: + 1. py__init_dim_obs_pdaf + 2. py__obs_op_pdaf (for ensemble mean) + 3. py__init_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. py__init_obsvar_pdaf + (only relevant for adaptive forgetting factor schemes) + 6. py__prodRinvA_pdaf + 7. core ESTKF algorithm + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_put_state_en3dvar_estkf` + and :func:`pyPDAF.PDAF.omi_put_state_en3dvar_estkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble var) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf_put_state_en3dvar_estkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_hyb3dvar_lestkf(py__collect_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__prodrinva_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__cvt_pdaf, py__cvt_adj_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, + py__init_obs_f_pdaf, py__init_obs_l_pdaf, py__prodrinva_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__g2l_obs_pdaf, py__init_obsvar_pdaf, py__init_obsvar_l_pdaf, + py__prepoststep_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf` + or :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Hybrid 3DEnVar for a single DA step using + non-diagnoal observation error covariance matrix + without post-processing, distributing analysis, + and setting next observation step, where + the background error covariance is hybridised by + a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + + Compared to :func:`pyPDAF.PDAF.assimilate_hyb3dvar_lestkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + LESTKF in this implementation. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. The iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core DA algorithm + 7. py__cvt_pdaf + 8. py__cvt_ens_pdaf + 9. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__init_obs_pdaf + (if global adaptive forgetting factor + `type_forget=1` in :func:`pyPDAF.PDAF.init`) + 5. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise mean ensemble in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting + factor `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf` + and :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble var) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_f_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Size of the full observation vector + + Callback Returns + ---------------- + observation_f : ndarray[np.float64, ndim=1] + Full vector of observations + Array shape: (dim_obs_f) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from state on local analysis domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.init_obs_f_pdaf = py__init_obs_f_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf_put_state_hyb3dvar_lestkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__init_obs_f_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_netf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__prepoststep_pdaf, + py__likelihood_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_put_state_global` + or :func:`pyPDAF.PDAF.omi_put_state_nonlin_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + This function will use + Nonlinear Ensemble Transform Filter (NETF) [1]_ + for a single DA step. + + Compared to :func:`pyPDAF.PDAF.assimilate_netf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The nonlinear filter computes the distribution up to + the second moment similar to KF but using + a nonlinear weighting similar to + particle filter. This leads to an equal weights + assumption for prior ensemble. + The function should be called at each model step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__init_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. py__likelihood_pdaf + 7. core DA algorithm + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_put_state_global` + and :func:`pyPDAF.PDAF.omi_put_state_nonlin_nondiagR` + + References + ---------- + .. [1] Tödter, J., and B. Ahrens, 2015: + A second-order exact ensemble square root filter + for nonlinear data assimilation. Mon. Wea. Rev., + 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__likelihood_pdaf : Callable + Compute observation likelihood for an ensemble member + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + resid : ndarray[np.float64, ndim=1] + Input vector holding the residual + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + likely : double + Output value of the likelihood + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.likelihood_pdaf = py__likelihood_pdaf + cdef int outflag + with nogil: + c__pdaf_put_state_netf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__likelihood_pdaf, &outflag) + + return outflag + + +def put_state_etkf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__prepoststep_pdaf, + py__prodrinva_pdaf, py__init_obsvar_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_put_state_global` + or :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR`. + + PDAFlocal-OMI modules require fewer user-supplied + functions and improved efficiency. + + Using ETKF (ensemble transform Kalman filter) [1]_ for a single DA step without OMI. + The implementation is baed on [2]_. + + Compared to :func:`pyPDAF.PDAF.assimilate_etkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for ensemble mean) + 5. py__init_obs_pdaf + 6. py__obs_op_pdaf (for each ensemble member) + 7. py__init_obsvar_pdaf (only relevant for + adaptive forgetting factor schemes) + 8. py__prodRinvA_pdaf + 9. core DA algorithm + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_put_state_global` + and :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR` + + References + ---------- + .. [1] Bishop, C. H., B. J. Etherton, and S. J. Majumdar (2001) + Adaptive Sampling with the Ensemble Transform Kalman Filter. + Part I: Theoretical Aspects. Mon. Wea. Rev., 129, 420–436, + doi: 10.1175/1520-0493(2001)129<0420:ASWTET>2.0.CO;2. + .. [2] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. doi:10.1175/MWR-D-11-00102.1 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + cdef int outflag + with nogil: + c__pdaf_put_state_etkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__init_obsvar_pdaf, &outflag) + + return outflag + + +def put_state_ensrf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__init_obsvars_pdaf, + py__localize_covar_serial_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obsvars_pdaf : Callable + Initialize vector of observation error variances + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Dimension of full observation vector + + Callback Returns + ---------------- + var_f : ndarray[np.float64, ndim=1] + vector of observation error variances + Array shape: (dim_obs_f) + + py__localize_covar_serial_pdaf : Callable + Apply localization for single-observation vectors + + Callback Parameters + ------------------- + iobs : int + Index of current observation + dim_p : int + Process-local state dimension + dim_obs : int + Number of observations + hp_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HP for observation iobs + Array shape: (dim_p) + hxy_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HX(HX_all) for full observations + Array shape: (dim_obs) + + Callback Returns + ---------------- + hp_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HP for observation iobs + Array shape: (dim_p) + hxy_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HX(HX_all) for full observations + Array shape: (dim_obs) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obsvars_pdaf = py__init_obsvars_pdaf + pdaf_cb.localize_covar_serial_pdaf = py__localize_covar_serial_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf_put_state_ensrf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obsvars_pdaf, + pdaf_cb.c__localize_covar_serial_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_enkf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__prepoststep_pdaf, + py__add_obs_err_pdaf, py__init_obs_covar_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_put_state_global` + or :func:`pyPDAF.PDAF.omi_put_state_enkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Stochastic EnKF (ensemble Kalman filter) [1]_ for a single DA step without OMI. + + Compared to :func:`pyPDAF.PDAF.assimilate_enkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for ensemble mean) + 5. py__add_obs_err_pdaf + 6. py__init_obs_pdaf + 7. py__init_obscovar_pdaf + 8. py__obs_op_pdaf (for each ensemble member) + 9. core DA algorithm + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_put_state_global` + and :func:`pyPDAF.PDAF.omi_put_state_enkf_nondiagR` + + References + ---------- + .. [1] Evensen, G. (1994), + Sequential data assimilation with a + nonlinear quasi-geostrophic model + using Monte Carlo methods to forecast error statistics, + J. Geophys. Res., 99(C5), 10143–10162, doi:10.1029/94JC00572. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__add_obs_err_pdaf : Callable + Add obs error covariance R to HPH in EnKF + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Dimension of observation vector + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + py__init_obs_covar_pdaf : Callable + Initialize obs. error cov. matrix R in EnKF + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs : int + Global size of observation vector + dim_obs_p : int + Size of process-local observation vector + obs_p : ndarray[np.float64, ndim=1] + Process-local vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + covar : ndarray[np.float64, ndim=2] + Observation error covariance matrix + Array shape: (dim_obs_p,dim_obs_p) + isdiag : bint + + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + cdef int outflag + with nogil: + c__pdaf_put_state_enkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, &outflag) + + return outflag + + +def put_state_seik(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__prepoststep_pdaf, + py__prodrinva_pdaf, py__init_obsvar_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_put_state_global` + or :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + This function will use + singular evolutive interpolated Kalman filter [1]_ for + a single DA step. + + Compared to :func:`pyPDAF.PDAF.assimilate_seik`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. + The next DA step will not be assigned by user-supplied + functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The function should be called at each model step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for ensemble mean) + 5. py__init_obs_pdaf + 6. py__obs_op_pdaf (for each ensemble member) + 7. py__init_obsvar_pdaf (only relevant for + adaptive forgetting factor schemes) + 8. py__prodRinvA_pdaf + 9. core DA algorithm + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_put_state_global` + and :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR` + + References + ---------- + .. [1] Pham, D. T., Verron, J., & Roubaud, M. C. (1998). + A singular evolutive extended Kalman filter + for data assimilation + in oceanography. Journal of Marine systems, 16(3-4), 323-340. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + cdef int outflag + with nogil: + c__pdaf_put_state_seik(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__init_obsvar_pdaf, &outflag) + + return outflag + + +def put_state_generate_obs(py__collect_state_pdaf, py__init_dim_obs_f_pdaf, + py__obs_op_f_pdaf, py__init_obserr_f_pdaf, py__get_obs_f_pdaf, + py__prepoststep_pdaf): + """Generation of synthetic observations + based on given error statistics and observation operator + without post-processing, distributing analysis, + and setting next observation step. + + When diagonal observation error covariance matrix is used, + it is recommended to use + :func:`pyPDAF.PDAF.omi_generate_obs` functionalities + for fewer user-supplied functions and improved efficiency. + + The generated synthetic observations are + based on each member of model forecast. + Therefore, an ensemble of observations can be obtained. + In a typical experiment, + one may only need one ensemble member. + + Compared to :func:`pyPDAF.PDAF.generate_obs`, + this function has no :func:`get_state` call. + This means that the next DA step will + not be assigned by user-supplied functions. + This function is typically used when there + are not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The implementation strategy is similar to + an assimilation step. This means that, + one can reuse many user-supplied functions for + assimilation and observation generation. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pda + 5. py__init_obserr_f_pdaf + 6. py__get_obs_f_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obserr_f_pdaf : Callable + Initialize vector of observation error standard deviations + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Full dimension of observation vector + obs_f : ndarray[np.float64, ndim=1] + Full observation vector + Array shape: (dim_obs_f) + + Callback Returns + ---------------- + obserr_f : ndarray[np.float64, ndim=1] + Full observation error stddev + Array shape: (dim_obs_f) + + py__get_obs_f_pdaf : Callable + Provide observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Size of the full observation vector + + Callback Returns + ---------------- + observation_f : ndarray[np.float64, ndim=1] + Full vector of synthetic observations (process-local) + Array shape: (dim_obs_f) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.init_obserr_f_pdaf = py__init_obserr_f_pdaf + pdaf_cb.get_obs_f_pdaf = py__get_obs_f_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf_put_state_generate_obs(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__init_obserr_f_pdaf, + pdaf_cb.c__get_obs_f_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_pf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__prepoststep_pdaf, + py__likelihood_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_put_state_global` + or :func:`pyPDAF.PDAF.omi_put_state_nonlin_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + This function will use particle filter for a single DA step. + + Compared to :func:`pyPDAF.PDAF.assimilate_pf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + This is a fully nonlinear filter, and may require + a high number of ensemble members. + A review of particle filter can be found at [1]_. + The function should be called at each model step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__init_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. py__likelihood_pdaf + 7. core DA algorithm + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_put_state_global` + and :func:`pyPDAF.PDAF.omi_put_state_nonlin_nondiagR` + + References + ---------- + .. [1] Van Leeuwen, P. J., Künsch, H. R., Nerger, L., + Potthast, R., & Reich, S. (2019). + Particle filters for high‐dimensional + geoscience applications: + A review. + Quarterly Journal of the Royal Meteorological Society, + 145(723), 2335-2365. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__likelihood_pdaf : Callable + Compute observation likelihood for an ensemble member + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + resid : ndarray[np.float64, ndim=1] + Input vector holding the residual + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + likely : double + Output value of the likelihood + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.likelihood_pdaf = py__likelihood_pdaf + cdef int outflag + with nogil: + c__pdaf_put_state_pf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__likelihood_pdaf, &outflag) + + return outflag + + +def put_state_3dvar(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__prodrinva_pdaf, py__cvt_pdaf, + py__cvt_adj_pdaf, py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, + py__prepoststep_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_put_state_3dvar` + or :func:`pyPDAF.PDAF.omi_put_state_3dvar_nondiagR`. + + PDAF-OMI modules require fewer user-supplied + functions and improved efficiency. + + 3DVar DA for a single DA step. + + Compared to :func:`pyPDAF.PDAF.assimilate_3dvar`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will not + be assigned by user-supplied functions as well. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + When 3DVar is used, the background error covariance matrix + has to be modelled for cotrol variable transformation. + This is a deterministic filtering scheme so no ensemble + and parallelisation is needed. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. Iterative optimisation: + 1. py__cvt_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_pdaf + 6. core DA algorithm + 7. py__cvt_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_put_state_3dvar` + and :func:`pyPDAF.PDAF.omi_put_state_3dvar_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf_put_state_3dvar(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_estkf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__prepoststep_pdaf, + py__prodrinva_pdaf, py__init_obsvar_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_put_state_global` + or :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR` + instead of this function. + + OMI functions need fewer user-supplied functions + and improve DA efficiency. + + This function calls ESTKF + (error space transform Kalman filter) [1]_. + + Compared to :func:`pyPDAF.PDAF.assimilate_estkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The ESTKF is a more efficient equivalent to the ETKF. + + The function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for ensemble mean) + 5. py__init_obs_pdaf + 6. py__obs_op_pdaf (for each ensemble member) + 7. py__init_obsvar_pdaf (only relevant for + adaptive forgetting factor schemes) + 8. py__prodRinvA_pdaf + 9. core DA algorithm + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_put_state_global` + and :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR`. + + References + ---------- + .. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. doi:10.1175/MWR-D-11-00102.1 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + cdef int outflag + with nogil: + c__pdaf_put_state_estkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__init_obsvar_pdaf, &outflag) + + return outflag + + +def put_state_prepost(py__collect_state_pdaf, py__prepoststep_pdaf): + """It is used to preprocess and postprocess of the ensemble. + + No DA is performed in this function. + Compared to :func:`pyPDAF.PDAF.assimilate_prepost`, + this function does not set assimilation flag, + and does not distribute the processed ensemble to the model field. + This function also does not set the next assimilation step as + :func:`pyPDAF.PDAF.assimilate_prepost` + because it does not call :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf (preprocess, step < 0) + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf_put_state_prepost(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + diff --git a/pyPDAF/source/src/pyPDAF/PDAF/py.typed b/pyPDAF/source/src/pyPDAF/PDAF/py.typed new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/pyPDAF/source/src/pyPDAF/PDAF/setter.pxd b/pyPDAF/source/src/pyPDAF/PDAF/setter.pxd new file mode 100644 index 0000000000000000000000000000000000000000..542b1cd608921065013fce4e0fd82a03129621e4 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/setter.pxd @@ -0,0 +1,30 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t + +cdef extern void c__pdaf_set_comm_pdaf( + int* in_comm_pdaf) noexcept nogil; + +cdef extern void c__pdaf_set_debug_flag( + int* debugval) noexcept nogil; + +cdef extern void c__pdaf_set_ens_pointer(CFI_cdesc_t* ens_ptr, + int* status) noexcept nogil; + +cdef extern void c__pdaf_set_iparam(int* id, int* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_set_memberid( + int* memberid) noexcept nogil; + +cdef extern void c__pdaf_set_offline_mode( + int* screen) noexcept nogil; + +cdef extern void c__pdaf_set_rparam(int* id, double* value, + int* flag) noexcept nogil; + +cdef extern void c__pdaf_set_seedset( + int* seedset_in) noexcept nogil; + +cdef extern void c__pdaf_set_smootherens(CFI_cdesc_t* sens_point, + int* maxlag, int* status) noexcept nogil; + + diff --git a/pyPDAF/source/src/pyPDAF/PDAF/setter.pyi b/pyPDAF/source/src/pyPDAF/PDAF/setter.pyi new file mode 100644 index 0000000000000000000000000000000000000000..3f9efc9c2e2e3ca2bab58b5a1a549cc03cb69d69 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/setter.pyi @@ -0,0 +1,199 @@ +# pylint: disable=unused-argument +"""stub file for setter.pyx""" +import typing +import numpy as np + + +def set_comm_pdaf(in_comm_pdaf: int) -> None: + """Set the MPI communicator used by PDAF. + + By default, PDAF assumes it can use all available + processes, i.e., `MPI_COMM_WORLD`. + By using this function, we limit the number of processes + that can be used by PDAF to given MPI communicator. + + Parameters + ---------- + in_comm_pdaf : int + MPI communicator for PDAF + """ + +def set_debug_flag(debugval: int) -> None: + """Activate the debug output of the PDAF. + + Starting from the use of this function, + the debug infomation is sent to screen output. + The screen output end when the debug flag is + set to 0 by this function. + + For the sake of simplicity, + we recommend using debugging output for + a single local domain, e.g. + `if domain_p == 1: pyPDAF.PDAF.set_debug_flag(1)` + + Parameters + ---------- + debugval : int + Value for debugging flag + """ + +def set_ens_pointer() -> typing.Tuple[np.ndarray, int]: + """Return the ensemble in a numpy array. + + Here the internal array data has the same memoery address + as PDAF ensemble array allowing for manual ensemble modification. + + Returns + ------- + ens_ptr_np : np.ndarray + Numpy array view of the ensemble + status : int + Status flag + """ + +def set_iparam(idval: int, value: int, flag: int) -> int: + """Set integer parameters for PDAF. + + The integer parameters specific to a DA method can be set in the array + `param_int` that is an argument of :func:`pyPDAF.PDAF.init` + (see the page on + `initializing PDAF `_). + + This function provides an alternative way. + Instead of providing all parameters in the call to :func:`pyPDAF.PDAF.init`, + one can provide only the required minimum options for this call. + Afterwards, one can then call this function for each integer parameter + that one intends to specify differently from the default value. + An advantage of using this function is that one only needs to call it + for parameters that one intends to change, while in the call to + :func:`pyPDAF.PDAF.init` all parameters up to the index one intends to change + have to be specified, even if one does not want to change a parameter value. + + The routine is usually called by all processes after the call to + :func:`pyPDAF.PDAF.init` in init_pdaf. One can also call the routine at a + later time during an assimilation process to change parameters. + The parameter will be set for the DA method that was specified + in the call to :func:`pyPDAF.PDAF.init`. + + Parameters + ---------- + idval : int + Index of parameter + value : int + Parameter value + flag : int + Status flag: 0 for no error + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + +def set_memberid(memberid: int) -> int: + """Set the ensemble member index to given value. + + Parameters + ---------- + memberid : int + Index in the local ensemble + + Returns + ------- + memberid : int + Index in the local ensemble + """ + +def set_offline_mode(screen: int) -> None: + """Activate offline mode of PDAF. + + Parameters + ---------- + screen : int + Verbosity flag + """ + +def set_rparam(idval: int, value: float, flag: int) -> int: + """Set floating-point parameters for PDAF. + + The floating-point parameters specific to a DA method can be set in the array + `filter_param_r` that is an argument of :func:`pyPDAF.PDAF.init` + (see the page on + `initializing PDAF `_). + + This function provides an alternative way. + Instead of providing all parameters in the call to :func:`pyPDAF.PDAF.init`, + one can provide only the required minimum options for this call. + Afterwards, one can then call this function for each floating-point parameter + that one intends to specify differently from the default value. + An advantage of using this function is that one only needs to call it + for parameters that one intends to change, while in the call to + :func:`pyPDAF.PDAF.init` all parameters up to the index one intends to change + have to be specified, even if one does not want to change a parameter value. + + The routine is usually called by all processes after the call to + :func:`pyPDAF.PDAF.init` in init_pdaf. One can also call the routine at a + later time during an assimilation process to change parameters. + The parameter will be set for the DA method that was specified + in the call to :func:`pyPDAF.PDAF.init`. + + Parameters + ---------- + idval : int + Index of parameter + value : float + Parameter value + flag : int + Status flag: 0 for no error + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + +def set_seedset(seedset_in: int) -> None: + """Choose a seedset for the random number generator used in PDAF. + + Parameters + ---------- + seedset_in : int + Seedset index (1-20) + """ + +def set_smoother_ens(maxlag: int) -> typing.Tuple[np.ndarray, int]: + """Get a pointer to smoother ensemble. + + When smoother is used, the smoothed ensemble states + at earlier times are stored in an internal array of PDAF. + To be able to smooth post times, + the smoother algorithm must have access to the past ensembles. + + In this function, the user can obtain a numpy array of + smoother ensemble. This array has the same memory address + as the internal PDAF smoother ensemble array. + This allows for manual modification of the smoother ensemble. + + In the offline mode the user has to manually + fill the smoother ensemble array + from ensembles read in from files. + This function is typically called in + :func:`py__init_ens_pdaf` in the call to + :func:`pyPDAF.PDAF.PDAF_init`. + + In the online mode, the smoother array is filled + automatically during the cycles of forecast phases and analysis steps. + + Parameters + ---------- + maxlag : int + Number of past timesteps in sens + + Returns + ------- + sens_point : ndarray[np.float64, ndim=3] + Pointer to smoother array + Array shape: (:,:,:) + status : int + Status flag, + """ diff --git a/pyPDAF/source/src/pyPDAF/PDAF/setter.pyx b/pyPDAF/source/src/pyPDAF/PDAF/setter.pyx new file mode 100644 index 0000000000000000000000000000000000000000..6ce758b67f4164435f7509f5f64bb344c16aa9e4 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF/setter.pyx @@ -0,0 +1,283 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + +def set_comm_pdaf(int in_comm_pdaf): + """set_comm_pdaf(in_comm_pdaf:int) -> None + + Set the MPI communicator used by PDAF. + + By default, PDAF assumes it can use all available + processes, i.e., `MPI_COMM_WORLD`. + By using this function, we limit the number of processes + that can be used by PDAF to given MPI communicator. + + Parameters + ---------- + in_comm_pdaf : int + MPI communicator for PDAF + """ + with nogil: + c__pdaf_set_comm_pdaf(&in_comm_pdaf) + + + +def set_debug_flag(int debugval): + """set_debug_flag(debugval:int) -> None + + Activate the debug output of the PDAF. + + Starting from the use of this function, + the debug infomation is sent to screen output. + The screen output end when the debug flag is + set to 0 by this function. + + For the sake of simplicity, + we recommend using debugging output for + a single local domain, e.g. + `if domain_p == 1: pyPDAF.PDAF.set_debug_flag(1)` + + Parameters + ---------- + debugval : int + Value for debugging flag + + """ + with nogil: + c__pdaf_set_debug_flag(&debugval) + + + +def set_ens_pointer(): + """set_ens_pointer() -> Tuple[np.ndarray, int] + + Return the ensemble in a numpy array. + + Here the internal array data has the same memoery address + as PDAF ensemble array allowing for manual ensemble modification. + + Returns + ------- + ens_ptr_np : np.ndarray + Numpy array view of the ensemble + status : int + Status flag + """ + cdef CFI_cdesc_rank2 ens_ptr_cfi + cdef CFI_cdesc_t *ens_ptr_ptr = &ens_ptr_cfi + cdef int status + with nogil: + c__pdaf_set_ens_pointer(ens_ptr_ptr, &status) + + cdef CFI_index_t ens_ptr_subscripts[2] + ens_ptr_subscripts[0] = 0 + ens_ptr_subscripts[1] = 0 + cdef double * ens_ptr_ptr_np + ens_ptr_ptr_np = CFI_address(ens_ptr_ptr, ens_ptr_subscripts) + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ens_ptr_np = np.asarray( ens_ptr_ptr_np, order="F") + return ens_ptr_np, status + + +def set_iparam(int idval, int value, int flag): + """set_iparam(idval: int, value: int, flag: int) -> int + + Set integer parameters for PDAF. + + The integer parameters specific to a DA method can be set in the array + `filter_param_i` that is an argument of :func:`pyPDAF.PDAF.init` + (see the page on `initializing PDAF `_). + + This function provides an alternative way. + Instead of providing all parameters in the call to :func:`pyPDAF.PDAF.init`, + one can provide only the required minimum options for this call. + Afterwards, one can then call this function for each integer parameter + that one intends to specify differently from the default value. + An advantage of using this function is that one only needs to call it + for parameters that one intends to change, while in the call to + :func:`pyPDAF.PDAF.init` all parameters up to the index one intends to change + have to be specified, even if one does not want to change a parameter value. + + The routine is usually called by all processes after the call to + :func:`pyPDAF.PDAF.init` in init_pdaf. One can also call the routine at a + later time during an assimilation process to change parameters. + The parameter will be set for the DA method that was specified + in the call to :func:`pyPDAF.PDAF.init`. + + Parameters + ---------- + idval : int + Index of parameter + value : int + Parameter value + flag : int + Status flag: 0 for no error + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + with nogil: + c__pdaf_set_iparam(&idval, &value, &flag) + + return flag + + +def set_memberid(int memberid): + """set_memberid(int memberid) -> int + + Set the ensemble member index to given value. + + Parameters + ---------- + memberid : int + Index in the local ensemble + + Returns + ------- + memberid : int + Index in the local ensemble + """ + with nogil: + c__pdaf_set_memberid(&memberid) + + return memberid + + +def set_offline_mode(int screen): + """set_offline_mode(screen: int) -> None + + Activate offline mode of PDAF. + + Parameters + ---------- + screen : int + Verbosity flag + + """ + with nogil: + c__pdaf_set_offline_mode(&screen) + + + +def set_rparam(int idval, double value, int flag): + """set_rparam(idval: int, value: float, flag: int) -> int + + Set floating-point parameters for PDAF. + + The floating-point parameters specific to a DA method can be set in the array + `filter_param_r` that is an argument of :func:`pyPDAF.PDAF.init` + (see the page on `initializing PDAF `_). + + This function provides an alternative way. + Instead of providing all parameters in the call to :func:`pyPDAF.PDAF.init`, + one can provide only the required minimum options for this call. + Afterwards, one can then call this function for each floating-point parameter + that one intends to specify differently from the default value. + An advantage of using this function is that one only needs to call it + for parameters that one intends to change, while in the call to + :func:`pyPDAF.PDAF.init` all parameters up to the index one intends to change + have to be specified, even if one does not want to change a parameter value. + + The routine is usually called by all processes after the call to + :func:`pyPDAF.PDAF.init` in init_pdaf. One can also call the routine at a + later time during an assimilation process to change parameters. + The parameter will be set for the DA method that was specified + in the call to :func:`pyPDAF.PDAF.init`. + + Parameters + ---------- + idval : int + Index of parameter + value : float + Parameter value + flag : int + Status flag: 0 for no error + + Returns + ------- + flag : int + Status flag: 0 for no error + """ + with nogil: + c__pdaf_set_rparam(&idval, &value, &flag) + + return flag + + +def set_seedset(int seedset_in): + """set_seedset(seedset_in: int) -> None + + Choose a seedset for the random number generator used in PDAF. + + Parameters + ---------- + seedset_in : int + Seedset index (1-20) + + """ + with nogil: + c__pdaf_set_seedset(&seedset_in) + + + +def set_smoother_ens(int maxlag): + """set_smoother_ens(maxlag: int) -> Tuple[np.ndarray, int] + + Get a pointer to smoother ensemble. + + When smoother is used, the smoothed ensemble states + at earlier times are stored in an internal array of PDAF. + To be able to smooth post times, + the smoother algorithm must have access to the past ensembles. + + In this function, the user can obtain a numpy array of + smoother ensemble. This array has the same memory address + as the internal PDAF smoother ensemble array. + This allows for manual modification of the smoother ensemble. + + In the offline mode the user has to manually + fill the smoother ensemble array + from ensembles read in from files. + This function is typically called in + :func:`py__init_ens_pdaf` in the call to + :func:`pyPDAF.PDAF.PDAF_init`. + + In the online mode, the smoother array is filled + automatically during the cycles of forecast phases and analysis steps. + + Parameters + ---------- + maxlag : int + Number of past timesteps in sens + + Returns + ------- + sens_point : ndarray[np.float64, ndim=3] + Pointer to smoother array + Array shape: (:,:,:) + status : int + Status flag, + """ + cdef CFI_cdesc_rank3 sens_point_cfi + cdef CFI_cdesc_t *sens_point_ptr = &sens_point_cfi + cdef int status + with nogil: + c__pdaf_set_smootherens(sens_point_ptr, &maxlag, &status) + + cdef CFI_index_t sens_point_subscripts[3] + sens_point_subscripts[0] = 0 + sens_point_subscripts[1] = 0 + sens_point_subscripts[2] = 0 + cdef double * sens_point_ptr_np + sens_point_ptr_np = CFI_address(sens_point_ptr, sens_point_subscripts) + cdef cnp.ndarray[cnp.float64_t, ndim=3, mode="fortran", negative_indices=False, cast=False] sens_point_np = np.asarray( sens_point_ptr_np, order="F") + return sens_point_np, status + + + + diff --git a/pyPDAF/source/src/pyPDAF/PDAF3/__init__.py b/pyPDAF/source/src/pyPDAF/PDAF3/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b62b4e34f4a4a5897d05769410b488c1616bf29a --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF3/__init__.py @@ -0,0 +1,25 @@ +"""Namespace for PDAF3 module.""" +from ._pdaf3_c import init, init_forecast, set_parallel +from .assim import assimilate, assim_offline, \ + assimilate_3dvar_all, assim_offline_3dvar_all, \ + assimilate_local_nondiagr, assimilate_global_nondiagr, \ + assimilate_lnetf_nondiagr, assimilate_lknetf_nondiagr, \ + assimilate_enkf_nondiagr, assimilate_nonlin_nondiagr, \ + assimilate_3dvar_nondiagr, assimilate_en3dvar_estkf_nondiagr, \ + assimilate_en3dvar_lestkf_nondiagr, \ + assimilate_hyb3dvar_estkf_nondiagr, \ + assimilate_hyb3dvar_lestkf_nondiagr, \ + assim_offline_local_nondiagr, \ + assim_offline_global_nondiagr, \ + assim_offline_lnetf_nondiagr, \ + assim_offline_lknetf_nondiagr, \ + assim_offline_enkf_nondiagr, \ + assim_offline_lenkf_nondiagr, \ + assim_offline_nonlin_nondiagr, \ + assim_offline_3dvar_nondiagr, \ + assim_offline_en3dvar_estkf_nondiagr, \ + assim_offline_en3dvar_lestkf_nondiagr, \ + assim_offline_hyb3dvar_estkf_nondiagr, \ + assim_offline_hyb3dvar_lestkf_nondiagr, \ + generate_obs, generate_obs_offline + diff --git a/pyPDAF/source/src/pyPDAF/PDAF3/_pdaf3_c.pxd b/pyPDAF/source/src/pyPDAF/PDAF3/_pdaf3_c.pxd new file mode 100644 index 0000000000000000000000000000000000000000..d918f8996fce805ea53e0626573963e644506d91 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF3/_pdaf3_c.pxd @@ -0,0 +1,17 @@ +cdef extern void c__pdaf3_init(int* filtertype, int* subtype, int* stepnull, + int* param_int, int* dim_pint, double* param_real, int* dim_preal, + void (*c__init_ens_pdaf)(int* , int* , int* , double* , double* , + double* , int* ), + int* in_screen, int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_init_forecast( + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + + +cdef extern void c__pdaf3_set_parallel(int* in_comm_pdaf, + int* in_comm_model, int* in_comm_filter, int* in_comm_couple, int* in_task_id, + int* in_n_modeltasks, bint* in_filterpe, int* flag) noexcept nogil; diff --git a/pyPDAF/source/src/pyPDAF/PDAF3/_pdaf3_c.pyi b/pyPDAF/source/src/pyPDAF/PDAF3/_pdaf3_c.pyi new file mode 100644 index 0000000000000000000000000000000000000000..e9821c950ce53358ad81b0b0d70b159973646d41 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF3/_pdaf3_c.pyi @@ -0,0 +1,161 @@ +# pylint: disable=unused-argument +"""Stub file for PDAF3 module +""" +from typing import Callable, Tuple +import numpy as np + +def init( + filtertype: int, + subtype: int, + stepnull: int, + param_int: np.ndarray, + dim_pint: int, + param_real: np.ndarray, + dim_preal: int, + py__init_ens_pdaf: Callable, + in_screen: int +) -> Tuple[np.ndarray, np.ndarray, int]: + """Initialise the PDAF system. + + It is called once at the beginning of the assimilation. + The function has to be used in tandem with :func:`pyPDAF.PDAF3.set_parallel`. + + The function specifies the type of DA methods, + parameters of the filters, the MPI communicators, + and other parallel options. + The filter options including `filtertype`, `subtype`, + `param_int`, and `param_real` + are introduced in + `PDAF filter options wiki page `_. + Note that the size of `param_int` and `param_real` depends on + the filter type and subtype. However, for most filters, + they require at least the state vector size and ensemble size + for `param_int`, and the forgetting factor for `param_real`. + + This function also asks for a user-supplied function + :func:`py__init_ens_pdaf`. + This function is designed to provides an initial ensemble + to the internal PDAF ensemble array. + The internal PDAF ensemble then can be distributed to + initialise the model forecast using + :func:`pyPDAF.PDAF.get_state`. + This user-supplied function can be empty if the model + has already read the ensemble from restart files. + + Parameters + ---------- + filtertype : int + Type of filter + subtype : int + Sub-type of filter + stepnull : int + Initial time step of assimilation + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + dim_pint : int + Number of integer parameters + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + dim_preal : int + Number of real parameter + py__init_ens_pdaf : Callable + Initialise ensemble array in PDAF + in_screen : int + Control screen output: + + Returns + ------- + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + outflag : int + Status flag, 0: no error, error codes: + """ + +def init_forecast( + py__next_observation_pdaf: Callable, + py__distribute_state_pdaf: Callable, + py__prepoststep_pdaf: Callable, + outflag: int +) -> int: + """The routine PDAF_init_forecast has to be called once at the end of the + initialization of PDAF/start of DA cycles. + + This function has the purpose to initialize the model fields to be + propagated from the array holding the ensemble states. In addition, + the function initializes the information on how many time steps have to be + performed in the upcoming forecast phase before the next assimilation step, + and an exit flag indicating whether further model integrations have to be computed. + These variables are used internally in PDAF and can be retrieved by + the user by calling PDAF_get_fcst_info. + + Parameters + ---------- + py__next_observation_pdaf : Callable + Get the number of time steps to be computed in the forecast phase. + See details for :func:`pyPDAF.pdaf_c_cb_interface.c__next_observation_pdaf`. + py__distribute_state_pdaf : Callable + Distribute a state vector from pdaf to the model/any arrays + See details for :func:`pyPDAF.pdaf_c_cb_interface.c__distribute_state_pdaf`. + py__prepoststep_pdaf : Callable + Process ensemble before or after DA. + See details for :func:`pyPDAF.pdaf_c_cb_interface.c__prepoststep_pdaf`. + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + +def set_parallel( + in_comm_pdaf: int, + in_comm_model: int, + in_comm_filter: int, + in_comm_couple: int, + in_task_id: int, + in_n_modeltasks: int, + in_filterpe: bool, + flag: int +) -> int: + """Set MPI communicators and parallelisation in PDAF. + + The MPI communicators asked by this function depends on + the parallelisation strategy. + For the default parallelisation strategy, the user + can use the parallelisation module + provided under in `example directory `_ + without modifications. + The parallelisation can differ based on online and offline cases. + Users can also refer to + `parallelisation documentation `_ for + explanations or modifications. + + Parameters + ---------- + in_comm_model : int + Model communicator + in_comm_filter : int + Filter communicator + in_comm_couple : int + Coupling communicator + in_task_id : int + Id of my ensemble task + in_n_modeltasks : int + Number of parallel model tasks + in_filterpe : bint + Is my PE a filter-PE? + flag: int + Status flag + + Returns + ------- + flag : int + Status flag, 0: no error, error codes: + """ diff --git a/pyPDAF/source/src/pyPDAF/PDAF3/_pdaf3_c.pyx b/pyPDAF/source/src/pyPDAF/PDAF3/_pdaf3_c.pyx new file mode 100644 index 0000000000000000000000000000000000000000..a5ef4a9508fd81b49193a66b2456c49e3498b785 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF3/_pdaf3_c.pyx @@ -0,0 +1,171 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb + +def init(int filtertype, int subtype, int stepnull, int [::1] param_int, + int dim_pint, double [::1] param_real, int dim_preal, + py__init_ens_pdaf, int in_screen): + """init(filtertype: int, subtype: int, stepnull: int, param_int: np.ndarray, dim_pint: int, param_real: np.ndarray, dim_preal: int, py__init_ens_pdaf: Callable, in_screen: int) -> Tuple[np.ndarray, np.ndarray, int] + + Initialise the PDAF system. + + It is called once at the beginning of the assimilation. + The function has to be used in tandem with :func:`pyPDAF.PDAF3.set_parallel`. + + The function specifies the type of DA methods, + parameters of the filters, the MPI communicators, + and other parallel options. + The filter options including `filtertype`, `subtype`, + `param_int`, and `param_real` + are introduced in + `PDAF filter options wiki page `_. + Note that the size of `param_int` and `param_real` depends on + the filter type and subtype. However, for most filters, + they require at least the state vector size and ensemble size + for `param_int`, and the forgetting factor for `param_real`. + + This function also asks for a user-supplied function + :func:`py__init_ens_pdaf`. + This function is designed to provides an initial ensemble + to the internal PDAF ensemble array. + The internal PDAF ensemble then can be distributed to + initialise the model forecast using + :func:`pyPDAF.PDAF.get_state`. + This user-supplied function can be empty if the model + has already read the ensemble from restart files. + + Parameters + ---------- + filtertype : int + Type of filter + subtype : int + Sub-type of filter + stepnull : int + Initial time step of assimilation + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + dim_pint : int + Number of integer parameters + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + dim_preal : int + Number of real parameter + py__init_ens_pdaf : Callable + Initialise ensemble array in PDAF + in_screen : int + Control screen output: + + Returns + ------- + param_int : ndarray[np.intc, ndim=1] + Integer parameter array + Array shape: (dim_pint) + param_real : ndarray[np.float64, ndim=1] + Real parameter array + Array shape: (dim_preal) + outflag : int + Status flag, 0: no error, error codes: + """ + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_int_np = np.asarray(param_int, dtype=np.intc, order="F") + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] param_real_np = np.asarray(param_real, dtype=np.float64, order="F") + pdaf_cb.init_ens_pdaf = py__init_ens_pdaf + cdef int outflag + with nogil: + c__pdaf3_init(&filtertype, &subtype, &stepnull, ¶m_int[0], + &dim_pint, ¶m_real[0], &dim_preal, + pdaf_cb.c__init_ens_pdaf, &in_screen, &outflag) + + return param_int_np, param_real_np, outflag + +def init_forecast(py__next_observation_pdaf, py__distribute_state_pdaf, + py__prepoststep_pdaf, int outflag): + """init_forecast(py__next_observation_pdaf: Callable, py__distribute_state_pdaf: Callable, py__prepoststep_pdaf: Callable, outflag: int) -> int + + The routine PDAF_init_forecast has to be called once at the end of the + initialization of PDAF/start of DA cycles. + + This function has the purpose to initialize the model fields to be + propagated from the array holding the ensemble states. In addition, + the function initializes the information on how many time steps have to be + performed in the upcoming forecast phase before the next assimilation step, + and an exit flag indicating whether further model integrations have to be computed. + These variables are used internally in PDAF and can be retrieved by + the user by calling PDAF_get_fcst_info. + + Parameters + ---------- + py__next_observation_pdaf : Callable + Get the number of time steps to be computed in the forecast phase. + See details for :func:`pyPDAF.pdaf_c_cb_interface.c__next_observation_pdaf`. + py__distribute_state_pdaf : Callable + Distribute a state vector from pdaf to the model/any arrays + See details for :func:`pyPDAF.pdaf_c_cb_interface.c__distribute_state_pdaf`. + py__prepoststep_pdaf : Callable + Process ensemble before or after DA. + See details for :func:`pyPDAF.pdaf_c_cb_interface.c__prepoststep_pdaf`. + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + with nogil: + c__pdaf3_init_forecast(pdaf_cb.c__next_observation_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + +def set_parallel(int in_comm_pdaf, + int in_comm_model, int in_comm_filter, int in_comm_couple, int in_task_id, + int in_n_modeltasks, bint in_filterpe, int flag): + """set_parallel(in_comm_pdaf: int, in_comm_model: int, in_comm_filter: int, in_comm_couple: int, in_task_id: int, in_n_modeltasks: int, in_filterpe: bool, flag: int) -> int + + Set MPI communicators and parallelisation in PDAF. + + The MPI communicators asked by this function depends on + the parallelisation strategy. + For the default parallelisation strategy, the user + can use the parallelisation module + provided under in `example directory `_ + without modifications. + The parallelisation can differ based on online and offline cases. + Users can also refer to `parallelisation documentation `_ for + explanations or modifications. + + Parameters + ---------- + in_comm_model : int + Model communicator + in_comm_filter : int + Filter communicator + in_comm_couple : int + Coupling communicator + in_task_id : int + Id of my ensemble task + in_n_modeltasks : int + Number of parallel model tasks + in_filterpe : bint + Is my PE a filter-PE? + flag: int + Status flag + + Returns + ------- + flag : int + Status flag, 0: no error, error codes: + """ + with nogil: + c__pdaf3_set_parallel(&in_comm_pdaf, &in_comm_model, &in_comm_filter, + &in_comm_couple, &in_task_id, &in_n_modeltasks, + &in_filterpe, &flag) + + return flag diff --git a/pyPDAF/source/src/pyPDAF/PDAF3/assim.pxd b/pyPDAF/source/src/pyPDAF/PDAF3/assim.pxd new file mode 100644 index 0000000000000000000000000000000000000000..1accda19bdae0b1249841efaefd0c1e7dcee2b90 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF3/assim.pxd @@ -0,0 +1,777 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t + + +cdef extern void c__pdaf3_assimilate_3dvar_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_en3dvar_estkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_en3dvar_lestkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_hyb3dvar_estkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_hyb3dvar_lestkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_3dvar_all( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_3dvar( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_en3dvar( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_en3dvar_estkf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_en3dvar_lestkf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_hyb3dvar( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_hyb3dvar_estkf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_hyb3dvar_lestkf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_3dvar_nondiagr( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_en3dvar_estkf_nondiagr( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_en3dvar_lestkf_nondiagr( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_hyb3dvar_estkf_nondiagr( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_hyb3dvar_lestkf_nondiagr( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_local( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_global( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_lenkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__localize_covar_pdaf)(int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_ensrf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__localize_covar_serial_pdaf)(int* , int* , int* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_local( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_global( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_lenkf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__localize_covar_pdaf)(int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_ensrf( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__localize_covar_serial_pdaf)(int* , int* , int* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_local_nondiagr( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_global_nondiagr( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_lnetf_nondiagr( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_lknetf_nondiagr( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__prodrinva_hyb_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* , double* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__likelihood_hyb_l_pdaf)(int* , int* , int* , double* , + double* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_enkf_nondiagr( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_lenkf_nondiagr( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__localize_covar_pdaf)(int* , int* , double* , double* ), + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assim_offline_nonlin_nondiagr( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__likelihood_pdaf)(int* , int* , double* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_3dvar_all( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_3dvar( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_en3dvar( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_en3dvar_estkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_en3dvar_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_hyb3dvar( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_hyb3dvar_estkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_hyb3dvar_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_local_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_global_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_lnetf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_lknetf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__prodrinva_hyb_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* , double* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__likelihood_hyb_l_pdaf)(int* , int* , int* , double* , + double* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_enkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_lenkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__localize_covar_pdaf)(int* , int* , double* , double* ), + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_assimilate_nonlin_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__likelihood_pdaf)(int* , int* , double* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_generate_obs( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__get_obs_f_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_generate_obs_offline( + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__get_obs_f_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/PDAF3/assim.pyi b/pyPDAF/source/src/pyPDAF/PDAF3/assim.pyi new file mode 100644 index 0000000000000000000000000000000000000000..1de2a37b989d9afbfc6352fad46e8026c590af86 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF3/assim.pyi @@ -0,0 +1,2211 @@ +from typing import Callable + + +def assimilate(py__collect_state_pdaf:Callable, + py__distribute_state_pdaf:Callable, + py__init_dim_obs_pdaf:Callable, + py__obs_op_pdaf:Callable, + py__init_n_domains_p_pdaf:Callable, + py__init_dim_l_pdaf:Callable, + py__init_dim_obs_l_pdaf:Callable, + py__prepoststep_pdaf:Callable, + py__next_observation_pdaf:Callable, outflag:int) -> int: + r"""Online ensemble filters and smoothers except for 3DVars for a single DA step + using diagnoal observation error covariance matrix. + + Here, this function call is used for + global stochastic EnKF [1]_, E(S)TKF [2]_, EAKF, EnSRF, + SEEK [2]_, SEIK [2]_, NETF [3]_, and particle filter [4]_. + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. core DA algorithm + 7. py__prepoststep_state_pdaf + 8. py__distribute_state_pdaf + 9. py__next_observation_pdaf + + References + ---------- + .. [1] Evensen, G. (1994), + Sequential data assimilation with + a nonlinear quasi-geostrophic model + using Monte Carlo methods to forecast error statistics, + J. Geophys. Res., 99(C5), 10143–10162, doi:10.1029/94JC00572. + .. [2] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + .. [3] Tödter, J., and B. Ahrens, 2015: + A second-order exact ensemble square root filter + for nonlinear data assimilation. Mon. Wea. Rev., + 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1. + .. [4] Van Leeuwen, P. J., Künsch, H. R., Nerger, L., + Potthast, R., & Reich, S. (2019). + Particle filters for high‐dimensional geoscience applications: + A review. Quarterly Journal of the Royal Meteorological Society, 145(723), 2335-2365. + + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + +def assim_offline(py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, + py__init_n_domains_p_pdaf: Callable, py__init_dim_l_pdaf: Callable, + py__init_dim_obs_l_pdaf: Callable, py__prepoststep_pdaf: Callable, outflag:int) -> int: + r"""Offline ensemble filters and smoothers except for 3DVars for a single DA step + using diagnoal observation error covariance matrix. + + Here, this function call is used for + global stochastic EnKF [1]_, E(S)TKF [2]_, EAKF, EnSRF, + SEEK [2]_, SEIK [2]_, NETF [3]_, and particle filter [4]_. + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_n_domains_p_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. core DA algorithm + 6. py__prepoststep_state_pdaf + + + References + ---------- + .. [1] Evensen, G. (1994), + Sequential data assimilation with + a nonlinear quasi-geostrophic model + using Monte Carlo methods to forecast error statistics, + J. Geophys. Res., 99(C5), 10143–10162, doi:10.1029/94JC00572. + .. [2] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + .. [3] Tödter, J., and B. Ahrens, 2015: + A second-order exact ensemble square root filter + for nonlinear data assimilation. Mon. Wea. Rev., + 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1. + .. [4] Van Leeuwen, P. J., Künsch, H. R., Nerger, L., + Potthast, R., & Reich, S. (2019). + Particle filters for high‐dimensional geoscience applications: + A review. Quarterly Journal of the Royal Meteorological Society, 145(723), 2335-2365. + + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + +def assimilate_3dvar_all(py__collect_state_pdaf: Callable, py__distribute_state_pdaf: Callable, + py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, py__cvt_ens_pdaf: Callable, + py__cvt_adj_ens_pdaf: Callable, py__cvt_pdaf: Callable, py__cvt_adj_pdaf: Callable, + py__obs_op_lin_pdaf: Callable, py__obs_op_adj_pdaf: Callable, py__init_n_domains_p_pdaf: Callable, + py__init_dim_l_pdaf: Callable, py__init_dim_obs_l_pdaf: Callable, py__prepoststep_pdaf: Callable, + py__next_observation_pdaf: Callable, outflag:int) -> int: + r"""Online assimilation for all types of 3DVar DA for a single DA step + using diagonal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assimilate_3dvar_nondiagR`, + :func:`pyPDAF.PDAF3.assimilate_en3dvar_lestkf_nondiagR`, + :func:`pyPDAF.PDAF3.assimilate_en3dvar_estkf_nondiagR`, + :func:`pyPDAF.PDAF3.assimilate_hyb3dvar_lestkf_nondiagR`, + :func:`pyPDAF.PDAF3.assimilate_hyb3dvar_estkf_nondiagR` + for non-diagonal observation error covariance matrix. + + When 3DVar is used, the background error covariance matrix + has to be modelled for cotrol variable transformation. + This is a deterministic filtering scheme + so no ensemble and parallelisation is needed. + This function should be called at each model time step. + + For parametrised 3DVar, user-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. Iterative optimisation: + 1. py__cvt_pdaf + 2. py__obs_op_lin_pdaf + 3. py__obs_op_adj_pdaf + 4. py__cvt_adj_pdaf + 5. core DA algorithm + 6. py__cvt_pdaf + 7. py__prepoststep_state_pdaf + 8. py__distribute_state_pdaf + 9. py__next_observation_pdaf + + For 3DEnVar, user-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. Starting the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__obs_op_adj_pdaf + 4. py__cvt_adj_ens_pdaf + 5. core DA algorithm + 6. py__cvt_ens_pdaf + 7. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. core DA algorithm + 8. py__prepoststep_state_pdaf + 9. py__distribute_state_pdaf + 10. py__next_observation_pdaf + + + For hybrid 3DVar, user-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. The iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_pdaf + 6. py__cvt_adj_ens_pdaf + 7. core DA algorithm + 6. py__cvt_pdaf + 7. py__cvt_ens_pdaf + 8. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. core DA algorithm + 9. py__prepoststep_state_pdaf + 10. py__distribute_state_pdaf + 11. py__next_observation_pdaf + + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + py__obs_op_lin_pdaf : Callable + Linearized observation operator + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + +def assim_offline_3dvar_all(py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, + py__cvt_ens_pdaf: Callable, py__cvt_adj_ens_pdaf: Callable, py__cvt_pdaf: Callable, + py__cvt_adj_pdaf: Callable, py__obs_op_lin_pdaf: Callable, py__obs_op_adj_pdaf: Callable, + py__init_n_domains_p_pdaf: Callable, py__init_dim_l_pdaf: Callable, + py__init_dim_obs_l_pdaf: Callable, py__prepoststep_pdaf: Callable) -> int: + r"""Offline assimilation for all types of 3DVar DA for a single DA step + using diagonal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.put_state_3dvar_nondiagR`, + :func:`pyPDAF.PDAF3.put_state_en3dvar_lestkf_nondiagR`, + :func:`pyPDAF.PDAF3.put_state_en3dvar_estkf_nondiagR`, + :func:`pyPDAF.PDAF3.put_state_hyb3dvar_lestkf_nondiagR`, + :func:`pyPDAF.PDAF3.put_state_hyb3dvar_estkf_nondiagR` + for non-diagonal observation error covariance matrix. + + When 3DVar is used, the background error covariance matrix + has to be modelled for cotrol variable transformation. + This is a deterministic filtering scheme + so no ensemble and parallelisation is needed. + This function should be called at each model time step. + + For parametrised 3DVar, user-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + 4. Iterative optimisation: + 1. py__cvt_pdaf + 2. py__obs_op_lin_pdaf + 3. py__obs_op_adj_pdaf + 4. py__cvt_adj_pdaf + 5. core DA algorithm + 5. py__cvt_pdaf + 6. py__prepoststep_state_pdaf + + For 3DEnVar, user-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + 4. Starting the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__obs_op_adj_pdaf + 4. py__cvt_adj_ens_pdaf + 5. core DA algorithm + 5. py__cvt_ens_pdaf + 6. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. core DA algorithm + 7. py__prepoststep_state_pdaf + + + For hybrid 3DVar, user-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + 4. The iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_pdaf + 6. py__cvt_adj_ens_pdaf + 7. core DA algorithm + 5. py__cvt_pdaf + 6. py__cvt_ens_pdaf + 7. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. core DA algorithm + 8. py__prepoststep_state_pdaf + + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + py__obs_op_lin_pdaf : Callable + Linearized observation operator + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + +def assimilate_local_nondiagr(py__collect_state_pdaf: Callable, + py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, + py__obs_op_pdaf: Callable, py__init_n_domains_p_pdaf: Callable, + py__init_dim_l_pdaf: Callable, py__init_dim_obs_l_pdaf: Callable, + py__prodrinva_l_pdaf: Callable, py__prepoststep_pdaf: Callable, + py__next_observation_pdaf: Callable, outflag: int) -> int: + r"""Online assimilation of domain local filters for a single DA step + using non-diagnoal observation error covariance matrix. + + Here, this function call is used for LE(S)TKF [1]_ and LSEIK [1]_ + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__init_obs_l_pdaf + 4. py__prodRinvA_l_pdaf + 5. core DA algorithm + 7. py__prepoststep_state_pdaf + 8. py__distribute_state_pdaf + 9. py__next_observation_pdaf + + References + ---------- + .. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + py__prodrinva_l_pdaf : Callable + Provide product of inverse of R with matrix A + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + +def assimilate_global_nondiagr(py__collect_state_pdaf: Callable, + py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, + py__obs_op_pdaf: Callable, py__prodrinva_pdaf: Callable, + py__prepoststep_pdaf: Callable, py__next_observation_pdaf: Callable) -> int: + r"""Online assimilation of global filters except for 3DVar and stochastic EnKF + for a single DA step using non-diagnoal observation + error covariance matrix. + + See :func:`pyPDAF.PDAF3.assimilate` + for diagonal observation error covariance matrix. + + Here, this function call is used for global, E(S)TKF [1]_, + SEIK [1]_. + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for ensemble mean) + 5. py__obs_op_pdaf (for each ensemble member) + 6. py__prodRinvA_pdaf + 7. core DA algorithm + 8. py__prepoststep_state_pdaf + 9. py__distribute_state_pdaf + 10. py__next_observation_pdaf + + References + ---------- + .. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__prodrinva_pdaf : Callable + Provide product of inverse of R with matrix A + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + +def assimilate_lnetf_nondiagr(py__collect_state_pdaf: Callable, + py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, + py__obs_op_pdaf: Callable, py__init_n_domains_p_pdaf: Callable, + py__init_dim_l_pdaf: Callable, py__init_dim_obs_l_pdaf: Callable, + py__likelihood_l_pdaf: Callable, py__prepoststep_pdaf: Callable, + py__next_observation_pdaf: Callable, outflag:int) -> int: + r"""Online assimilation of LNETF for a single DA step using + non-diagnoal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assimilate` for + using diagnoal observation error covariance matrix. + The non-linear filter is proposed in [1]_. + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__likelihood_l_pdaf + 4. core DA algorithm + 7. py__prepoststep_state_pdaf + 8. py__distribute_state_pdaf + 9. py__next_observation_pdaf + + References + ---------- + .. [1] Tödter, J., and B. Ahrens, 2015: + A second-order exact ensemble square root filter + for nonlinear data assimilation. Mon. Wea. Rev., + 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + py__likelihood_l_pdaf : Callable + Compute likelihood and apply localization + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + +def assimilate_lknetf_nondiagr(py__collect_state_pdaf: Callable, + py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, + py__init_n_domains_p_pdaf: Callable, py__init_dim_l_pdaf: Callable, + py__init_dim_obs_l_pdaf: Callable, py__prodrinva_l_pdaf: Callable, + py__prodrinva_hyb_l_pdaf: Callable, py__likelihood_l_pdaf: Callable, + py__likelihood_hyb_l_pdaf: Callable, py__prepoststep_pdaf: Callable, + py__next_observation_pdaf: Callable, outflag: int) -> int: + r"""Online assimilation of LKNETF for a single DA step using + non-diagonal observation error covariance matrix. + + + PDAFlocal-OMI modules require fewer user-supplied + functions and improved efficiency. + + LKNETF [1]_ for a single DA step using non-diagnoal + observation error covariance matrix. + See :func:`pyPDAF.PDAF3.assimilate` + for using diagnoal observation error covariance matrix. + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__prodRinvA_pdaf + 4. py__likelihood_l_pdaf + 5. core DA algorithm + 6. py__obs_op_pdaf + (only called with `HKN` and `HNK` options + called for each ensemble member) + 7. py__likelihood_hyb_l_pdaf + 8. py__prodRinvA_hyb_l_pdaf + 7. py__prepoststep_state_pdaf + 8. py__distribute_state_pdaf + 9. py__next_observation_pdaf + + References + ---------- + .. [1] Nerger, L.. (2022) + Data assimilation for nonlinear systems with + a hybrid nonlinear Kalman ensemble transform filter. + Q J R Meteorol Soc, 620–640. doi:10.1002/qj.4221 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + py__prodrinva_l_pdaf : Callable + Provide product of inverse of R with matrix A + py__prodrinva_hyb_l_pdaf : Callable + Product R^-1 A on local analysis domain with hybrid weight + py__likelihood_l_pdaf : Callable + Compute likelihood and apply localization + py__likelihood_hyb_l_pdaf : Callable + Compute likelihood and apply localization with tempering + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + +def assimilate_enkf_nondiagr(py__collect_state_pdaf: Callable, + py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, + py__add_obs_err_pdaf: Callable, py__init_obs_covar_pdaf: Callable, py__prepoststep_pdaf: Callable, + py__next_observation_pdaf: Callable) -> int: + r"""Online assimilation of global or Covariance localised stochastic EnKF + for a single DA step using non-diagonal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assimilate` + for diagonal observation error covariance matrix. + + This stochastic EnKF is implemented based on [1]_ + + This is the only scheme for covariance localisation with non-diagonal + observation error covariance matrix in PDAF. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. py__localize_pdaf + 6. py__add_obs_err_pdaf + 7. py__init_obscovar_pdaf + 8. py__obs_op_pdaf (repeated to reduce storage) + 9. core DA algorith + 10. py__prepoststep_state_pdaf + 11. py__distribute_state_pdaf + 12. py__next_observation_pdaf + + References + ---------- + .. [1] Houtekamer, P. L., and H. L. Mitchell (1998): + Data Assimilation Using an Ensemble Kalman Filter Technique. + Mon. Wea. Rev., 126, 796–811, + doi: 10.1175/1520-0493(1998)126<0796:DAUAEK>2.0.CO;2. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__add_obs_err_pdaf : Callable + Add observation error covariance matrix + py__init_obs_covar_pdaf : Callable + Initialize mean observation error variance + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + +def assimilate_lenkf_nondiagr(py__collect_state_pdaf: Callable, py__distribute_state_pdaf: Callable, + py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, + py__localize_covar_pdaf: Callable, py__add_obs_err_pdaf: Callable, py__init_obs_covar_pdaf: Callable, + py__prepoststep_pdaf: Callable, py__next_observation_pdaf: Callable) -> int: + r"""Covariance localised stochastic EnKF + for a single DA step using non-diagnoal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assimilate` or :func:`pyPDAF.PDAF3.assim_offline` + for diagnoal observation error covariance matrix. + + This stochastic EnKF is implemented based on [1]_ + + This is the only scheme for covariance localisation with non-diagonal + observation error covariance matrix in PDAF. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. py__localize_pdaf + 6. py__add_obs_err_pdaf + 7. py__init_obscovar_pdaf + 8. py__obs_op_pdaf (repeated to reduce storage) + 9. core DA algorith + 10. py__prepoststep_state_pdaf + 11. py__distribute_state_pdaf + 12. py__next_observation_pdaf + + References + ---------- + .. [1] Houtekamer, P. L., and H. L. Mitchell (1998): + Data Assimilation Using an Ensemble Kalman Filter Technique. + Mon. Wea. Rev., 126, 796–811, + doi: 10.1175/1520-0493(1998)126<0796:DAUAEK>2.0.CO;2. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__localize_covar_pdaf : Callable + Apply covariance localization + py__add_obs_err_pdaf : Callable + Add observation error covariance matrix + py__init_obs_covar_pdaf : Callable + Initialize mean observation error variance + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + +def assimilate_nonlin_nondiagr(py__collect_state_pdaf: Callable, + py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, + py__likelihood_pdaf: Callable, py__prepoststep_pdaf: Callable, + py__next_observation_pdaf: Callable) -> int: + r"""Online assimilation of global nonlinear filters for a single DA step + using non-diagonal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assimilate` + for diagonal observation error covariance matrix. + + Here, this function call is used for global NETF [1]_, + and particle filter [2]_. + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR` and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for ensemble mean) + 5. py__obs_op_pdaf (for each ensemble member) + 6. py__likelihood_pdaf + 7. core DA algorithm + 8. py__prepoststep_state_pdaf + 9. py__distribute_state_pdaf + 10. py__next_observation_pdaf + + References + ---------- + .. [1] Tödter, J., and B. Ahrens, 2015: + A second-order exact ensemble square root filter + for nonlinear data assimilation. Mon. Wea. Rev., + 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1. + .. [2] Van Leeuwen, P. J., Künsch, H. R., Nerger, L., + Potthast, R., & Reich, S. (2019). + Particle filters for high‐dimensional geoscience applications: + A review. Quarterly Journal of the Royal Meteorological Society, 145(723), 2335-2365. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__likelihood_pdaf : Callable + Compute likelihood + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + +def assimilate_3dvar_nondiagr(py__collect_state_pdaf: Callable, + py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, + py__prodrinva_pdaf: Callable, py__cvt_pdaf: Callable, py__cvt_adj_pdaf: Callable, + py__obs_op_lin_pdaf: Callable, py__obs_op_adj_pdaf: Callable, py__prepoststep_pdaf: Callable, + py__next_observation_pdaf: Callable) -> int: + r"""3DVar DA for a single DA step + using non-diagnoal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assimilate_3dvar_all` + for diagonal observation error covariance matrix. + + When 3DVar is used, the background error covariance matrix + has to be modelled for cotrol variable transformation. + This is a deterministic filtering scheme + so no ensemble and parallelisation is needed. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. Iterative optimisation: + 1. py__cvt_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_pdaf + 6. core DA algorithm + 6. py__cvt_pdaf + 7. py__prepoststep_state_pdaf + 8. py__distribute_state_pdaf + 9. py__next_observation_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__prodrinva_pdaf : Callable + Provide product R^-1 A + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + py__obs_op_lin_pdaf : Callable + Linearized observation operator + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + +def assimilate_en3dvar_estkf_nondiagr(py__collect_state_pdaf: Callable, + py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, + py__prodrinva_pdaf: Callable, py__cvt_ens_pdaf: Callable, py__cvt_adj_ens_pdaf: Callable, + py__obs_op_lin_pdaf: Callable, py__obs_op_adj_pdaf: Callable, py__prepoststep_pdaf: Callable, + py__next_observation_pdaf: Callable) -> int: + r"""3DEnVar for a single DA step + using non-diagnoal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assimilate_3dvar_all` + for diagonal observation error covariance matirx. + + Here, the background error covariance matrix is + estimated by an ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An ESTKF is used along with 3DEnVar to generate ensemble perturbations. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core 3DEnVar algorithm + 6. py__cvt_ens_pdaf + 7. ESTKF: + 1. py__init_dim_obs_pdaf + 2. py__obs_op_pdaf (for ensemble mean) + 3. py__obs_op_pdaf (for each ensemble member) + 4. py__prodRinvA_pdaf + 5. core ESTKF algorithm + 8. py__prepoststep_state_pdaf + 9. py__distribute_state_pdaf + 10. py__next_observation_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__prodrinva_pdaf : Callable + Provide product R^-1 A + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + py__obs_op_lin_pdaf : Callable + Linearized observation operator + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + +def assimilate_en3dvar_lestkf_nondiagr(py__collect_state_pdaf: Callable, + py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, + py__prodrinva_pdaf: Callable, py__cvt_ens_pdaf: Callable, py__cvt_adj_ens_pdaf: Callable, + py__obs_op_lin_pdaf: Callable, py__obs_op_adj_pdaf: Callable, py__prodrinva_l_pdaf: Callable, + py__init_n_domains_p_pdaf: Callable, py__init_dim_l_pdaf: Callable, + py__init_dim_obs_l_pdaf: Callable, py__prepoststep_pdaf: Callable, + py__next_observation_pdaf:Callable, outflag:int) -> int: + r"""3DEnVar for a single DA step where the ensemble anomaly + is generated by LESTKF using non-diagonal observation + error covariance matrix. + + PDAFlocal-OMI modules require fewer user-supplied + functions and improved efficiency. + + 3DEnVar for a single DA step where the ensemble anomaly + is generated by LESTKF + using non-diagnoal observation error covariance matrix. + The background error covariance matrix is estimated by ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An LESTKF is used to generate ensemble perturbations. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. Starting the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core DA algorithm + 6. py__cvt_ens_pdaf + 7. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__prodRinvA_l_pdaf + 4. core DA algorithm + 8. py__prepoststep_state_pdaf + 9. py__distribute_state_pdaf + 10. py__next_observation_pdaf + + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__prodrinva_pdaf : Callable + Provide product R^-1 A + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + py__obs_op_lin_pdaf : Callable + Linearized observation operator + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A and apply localizations + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + +def assimilate_hyb3dvar_estkf_nondiagr(py__collect_state_pdaf: Callable, + py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, + py__prodrinva_pdaf: Callable, py__cvt_ens_pdaf: Callable, py__cvt_adj_ens_pdaf: Callable, + py__cvt_pdaf: Callable, py__cvt_adj_pdaf: Callable, py__obs_op_lin_pdaf: Callable, + py__obs_op_adj_pdaf: Callable, py__prepoststep_pdaf: Callable, + py__next_observation_pdaf: Callable) -> int: + r"""Hybrid 3DEnVar for a single DA step + using non-diagnoal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assimilate_3dvar_all` + for diagonal observation error covariance matrix. + + Here the background error covariance is hybridised by + a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + ESTKF in this implementation. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. the iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core 3DEnVar algorithm + 6. py__cvt_pdaf + 7. py__cvt_ens_pdaf + 8. Perform ESTKF: + 1. py__init_dim_obs_pdaf + 2. py__obs_op_pdaf + (for ensemble mean) + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__prodRinvA_pdaf + 5. core ESTKF algorithm + 9. py__prepoststep_state_pdaf + 10. py__distribute_state_pdaf + 11. py__next_observation_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__prodrinva_pdaf : Callable + Provide product R^-1 A + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + py__obs_op_lin_pdaf : Callable + Linearized observation operator + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + +def assimilate_hyb3dvar_lestkf_nondiagr(py__collect_state_pdaf: Callable, + py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, + py__prodrinva_pdaf: Callable, py__cvt_ens_pdaf: Callable, py__cvt_adj_ens_pdaf: Callable, + py__cvt_pdaf: Callable, py__cvt_adj_pdaf: Callable, py__obs_op_lin_pdaf: Callable, + py__obs_op_adj_pdaf: Callable, py__prodrinva_l_pdaf: Callable, py__init_n_domains_p_pdaf: Callable, + py__init_dim_l_pdaf: Callable, py__init_dim_obs_l_pdaf: Callable, py__prepoststep_pdaf: Callable, + py__next_observation_pdaf: Callable, outflag:int) -> int: + r"""Hybrid 3DEnVar for a single DA step + using non-diagonal observation error covariance matrix. + + Here, the background error covariance is + hybridised by a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + LESTKF in this implementation. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. The iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core DA algorithm + 6. py__cvt_pdaf + 7. py__cvt_ens_pdaf + 8. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__prodRinvA_l_pdaf + 4. core DA algorithm + 9. py__prepoststep_state_pdaf + 10. py__distribute_state_pdaf + 11. py__next_observation_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A and apply localizations + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__next_observation_pdaf : Callable + Provide information on next forecast + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + +def assim_offline_local_nondiagr(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, + py__init_n_domains_p_pdaf:Callable, py__init_dim_l_pdaf:Callable, + py__init_dim_obs_l_pdaf:Callable, py__prodrinva_l_pdaf:Callable, + py__prepoststep_pdaf:Callable) -> int: + r"""Offline assimilation of domain local filters for a single DA step + using non-diagnoal observation error covariance matrix. + + Here, this function call is used for LE(S)TKF [1]_ and LSEIK [1]_ + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_n_domains_p_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__init_obs_l_pdaf + 4. py__prodRinvA_l_pdaf + 5. core DA algorithm + 6. py__prepoststep_state_pdaf + + References + ---------- + .. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prodrinva_l_pdaf : Callable + Provide product of inverse of R with matrix A + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + +def assim_offline_global_nondiagr(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, + py__prodrinva_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int: + r"""Offline assimilation of global filters except for 3DVar and stochastic EnKF + for a single DA step using non-diagnoal observation + error covariance matrix. + + See :func:`pyPDAF.PDAF3.assimilate` + for diagonal observation error covariance matrix. + + Here, this function call is used for global, E(S)TKF [1]_, + SEIK [1]_. + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf (for ensemble mean) + 4. py__obs_op_pdaf (for each ensemble member) + 5. py__prodRinvA_pdaf + 6. core DA algorithm + 7. py__prepoststep_state_pdaf + + References + ---------- + .. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prodrinva_pdaf : Callable + Provide product of inverse of R with matrix A + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + +def assim_offline_lnetf_nondiagr(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, + py__init_n_domains_p_pdaf:Callable, py__init_dim_l_pdaf:Callable, + py__init_dim_obs_l_pdaf:Callable, py__likelihood_l_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int: + r"""Offline assimilation of LNETF for a single DA step using + non-diagnoal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assim_offline` for + using diagnoal observation error covariance matrix. + The non-linear filter is proposed in [1]_. + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_n_domains_p_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__likelihood_l_pdaf + 4. core DA algorithm + 6. py__prepoststep_state_pdaf + + References + ---------- + .. [1] Tödter, J., and B. Ahrens, 2015: + A second-order exact ensemble square root filter + for nonlinear data assimilation. Mon. Wea. Rev., + 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__likelihood_l_pdaf : Callable + Compute likelihood and apply localization + + Returns + ------- + outflag : int + Status flag + """ + +def assim_offline_lknetf_nondiagr(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, + py__init_n_domains_p_pdaf:Callable, py__init_dim_l_pdaf:Callable, + py__init_dim_obs_l_pdaf:Callable, py__prodrinva_l_pdaf:Callable, + py__prodrinva_hyb_l_pdaf:Callable, py__likelihood_l_pdaf:Callable, py__likelihood_hyb_l_pdaf:Callable, + py__prepoststep_pdaf:Callable) -> int: + r"""Offline assimilation of LKNETF for a single DA step using + non-diagonal observation error covariance matrix. + + + PDAFlocal-OMI modules require fewer user-supplied + functions and improved efficiency. + + LKNETF [1]_ for a single DA step using non-diagnoal + observation error covariance matrix. + See :func:`pyPDAF.PDAF3.assimilate` + for using diagnoal observation error covariance matrix. + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_n_domains_p_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__prodRinvA_pdaf + 4. py__likelihood_l_pdaf + 5. core DA algorithm + 6. py__obs_op_pdaf + (only called with `HKN` and `HNK` options + called for each ensemble member) + 7. py__likelihood_hyb_l_pdaf + 8. py__prodRinvA_hyb_l_pdaf + 6. py__prepoststep_state_pdaf + + References + ---------- + .. [1] Nerger, L.. (2022) + Data assimilation for nonlinear systems with + a hybrid nonlinear Kalman ensemble transform filter. + Q J R Meteorol Soc, 620–640. doi:10.1002/qj.4221 + + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prodrinva_l_pdaf : Callable + Provide product of inverse of R with matrix A + + py__prodrinva_hyb_l_pdaf : Callable + Product R^-1 A on local analysis domain with hybrid weight + + py__likelihood_l_pdaf : Callable + Compute likelihood and apply localization + + py__likelihood_hyb_l_pdaf : Callable + Compute likelihood and apply localization with tempering + + Returns + ------- + outflag : int + Status flag + """ + +def assim_offline_enkf_nondiagr(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, + py__add_obs_err_pdaf:Callable, py__init_obs_covar_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int: + r"""Offline assimilation of global or Covariance localised stochastic EnKF + for a single DA step using non-diagonal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assim_offline` + for diagonal observation error covariance matrix. + + This stochastic EnKF is implemented based on [1]_ + + This is the only scheme for covariance localisation with non-diagonal + observation error covariance matrix in PDAF. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf (for each ensemble member) + 4. py__localize_pdaf + 5. py__add_obs_err_pdaf + 6. py__init_obscovar_pdaf + 7. py__obs_op_pdaf (repeated to reduce storage) + 8. core DA algorithm + 9. py__prepoststep_state_pdaf + + References + ---------- + .. [1] Houtekamer, P. L., and H. L. Mitchell (1998): + Data Assimilation Using an Ensemble Kalman Filter Technique. + Mon. Wea. Rev., 126, 796–811, + doi: 10.1175/1520-0493(1998)126<0796:DAUAEK>2.0.CO;2. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__add_obs_err_pdaf : Callable + Add observation error covariance matrix + + py__init_obs_covar_pdaf : Callable + Initialize mean observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + +def assim_offline_lenkf_nondiagr(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, + py__localize_covar_pdaf:Callable, py__add_obs_err_pdaf:Callable, + py__init_obs_covar_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int: + r"""Online assimilation of covariance localised stochastic EnKF + for a single DA step using non-diagonal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assim_offline` + for diagonal observation error covariance matrix. + + This stochastic EnKF is implemented based on [1]_ + + This is the only scheme for covariance localisation with non-diagonal + observation error covariance matrix in PDAF. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf (for each ensemble member) + 4. py__localize_pdaf + 5. py__add_obs_err_pdaf + 6. py__init_obscovar_pdaf + 7. py__obs_op_pdaf (repeated to reduce storage) + 8. core DA algorithm + 9. py__prepoststep_state_pdaf + + References + ---------- + .. [1] Houtekamer, P. L., and H. L. Mitchell (1998): + Data Assimilation Using an Ensemble Kalman Filter Technique. + Mon. Wea. Rev., 126, 796–811, + doi: 10.1175/1520-0493(1998)126<0796:DAUAEK>2.0.CO;2. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__localize_covar_pdaf : Callable + Apply covariance localization + + py__add_obs_err_pdaf : Callable + Add observation error covariance matrix + + py__init_obs_covar_pdaf : Callable + Initialize mean observation error variance + + Returns + ------- + outflag : int + Status flag + """ + +def assim_offline_nonlin_nondiagr(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, + py__likelihood_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int: + r"""Offline assimilation of global nonlinear filters for a single DA step + using non-diagonal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assim_offline` + for diagonal observation error covariance matrix. + + Here, this function call is used for global NETF [1]_, + and particle filter [2]_. + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR` and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf (for ensemble mean) + 4. py__obs_op_pdaf (for each ensemble member) + 5. py__likelihood_pdaf + 6. core DA algorithm + 7. py__prepoststep_state_pdaf + + References + ---------- + .. [1] Tödter, J., and B. Ahrens, 2015: + A second-order exact ensemble square root filter + for nonlinear data assimilation. Mon. Wea. Rev., + 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1. + .. [2] Van Leeuwen, P. J., Künsch, H. R., Nerger, L., + Potthast, R., & Reich, S. (2019). + Particle filters for high‐dimensional geoscience applications: + A review. Quarterly Journal of the Royal Meteorological Society, 145(723), 2335-2365. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__likelihood_pdaf : Callable + Compute likelihood + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + +def assim_offline_3dvar_nondiagr(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, + py__prodrinva_pdaf:Callable, py__cvt_pdaf:Callable, py__cvt_adj_pdaf:Callable, + py__obs_op_lin_pdaf:Callable, py__obs_op_adj_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int: + r"""Offline 3DVar DA for a single DA step + using non-diagnoal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assim_offline_3dvar_all` + for diagonal observation error covariance matrix. + + When 3DVar is used, the background error covariance matrix + has to be modelled for cotrol variable transformation. + This is a deterministic filtering scheme + so no ensemble and parallelisation is needed. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + 4. Iterative optimisation: + 1. py__cvt_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_pdaf + 6. core DA algorithm + 5. py__cvt_pdaf + 6. py__prepoststep_state_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__prodrinva_pdaf : Callable + Provide product R^-1 A + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + py__obs_op_lin_pdaf : Callable + Linearized observation operator + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + +def assim_offline_en3dvar_estkf_nondiagr(py__init_dim_obs_pdaf:Callable, + py__obs_op_pdaf:Callable, py__prodrinva_pdaf:Callable, py__cvt_ens_pdaf:Callable, + py__cvt_adj_ens_pdaf:Callable, py__obs_op_lin_pdaf:Callable, py__obs_op_adj_pdaf:Callable, + py__prepoststep_pdaf:Callable) -> int: + r"""Offline 3DEnVar for a single DA step + using non-diagnoal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assim_offline_3dvar_all` + for diagonal observation error covariance matirx. + + Here, the background error covariance matrix is + estimated by an ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An ESTKF is used along with 3DEnVar to generate ensemble perturbations. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + 4. the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core 3DEnVar algorithm + 5. py__cvt_ens_pdaf + 6. ESTKF: + 1. py__init_dim_obs_pdaf + 2. py__obs_op_pdaf (for ensemble mean) + 3. py__obs_op_pdaf (for each ensemble member) + 4. py__prodRinvA_pdaf + 5. core ESTKF algorithm + 7. py__prepoststep_state_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__prodrinva_pdaf : Callable + Provide product R^-1 A + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + py__obs_op_lin_pdaf : Callable + Linearized observation operator + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + +def assim_offline_en3dvar_lestkf_nondiagr(py__init_dim_obs_pdaf:Callable, + py__obs_op_pdaf:Callable, py__prodrinva_pdaf:Callable, py__cvt_ens_pdaf:Callable, + py__cvt_adj_ens_pdaf:Callable, py__obs_op_lin_pdaf:Callable, py__obs_op_adj_pdaf:Callable, + py__prodrinva_l_pdaf:Callable, py__init_n_domains_p_pdaf:Callable, py__init_dim_l_pdaf:Callable, + py__init_dim_obs_l_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int: + r"""Offline 3DEnVar for a single DA step where the ensemble anomaly + is generated by LESTKF using non-diagonal observation + error covariance matrix. + + PDAFlocal-OMI modules require fewer user-supplied + functions and improved efficiency. + + 3DEnVar for a single DA step where the ensemble anomaly + is generated by LESTKF + using non-diagnoal observation error covariance matrix. + The background error covariance matrix is estimated by ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An LESTKF is used to generate ensemble perturbations. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + 4. Starting the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core DA algorithm + 5. py__cvt_ens_pdaf + 6. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__prodRinvA_l_pdaf + 4. core DA algorithm + 7. py__prepoststep_state_pdaf + + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__prodrinva_pdaf : Callable + Provide product R^-1 A + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + py__obs_op_lin_pdaf : Callable + Linearized observation operator + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A and apply localizations + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + +def assim_offline_hyb3dvar_estkf_nondiagr(py__init_dim_obs_pdaf:Callable, + py__obs_op_pdaf:Callable, py__prodrinva_pdaf:Callable, py__cvt_ens_pdaf:Callable, + py__cvt_adj_ens_pdaf:Callable, py__cvt_pdaf:Callable, py__cvt_adj_pdaf:Callable, + py__obs_op_lin_pdaf:Callable, py__obs_op_adj_pdaf:Callable, + py__prepoststep_pdaf:Callable) -> int: + r"""Offline hybrid 3DEnVar for a single DA step + using non-diagnoal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assim_offline_3dvar_all` + for diagonal observation error covariance matrix. + + Here the background error covariance is hybridised by + a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + ESTKF in this implementation. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + 4. the iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core 3DEnVar algorithm + 5. py__cvt_pdaf + 6. py__cvt_ens_pdaf + 7. Perform ESTKF: + 1. py__init_dim_obs_pdaf + 2. py__obs_op_pdaf + (for ensemble mean) + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__prodRinvA_pdaf + 5. core ESTKF algorithm + 8. py__prepoststep_state_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__prodrinva_pdaf : Callable + Provide product R^-1 A + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + py__obs_op_lin_pdaf : Callable + Linearized observation operator + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + +def assim_offline_hyb3dvar_lestkf_nondiagr(py__init_dim_obs_pdaf:Callable, + py__obs_op_pdaf:Callable, py__prodrinva_pdaf:Callable, py__cvt_ens_pdaf:Callable, + py__cvt_adj_ens_pdaf:Callable, py__cvt_pdaf:Callable, py__cvt_adj_pdaf:Callable, + py__obs_op_lin_pdaf:Callable, py__obs_op_adj_pdaf:Callable, py__prodrinva_l_pdaf:Callable, + py__init_n_domains_p_pdaf:Callable, py__init_dim_l_pdaf:Callable, + py__init_dim_obs_l_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int: + r"""Offline hybrid 3DEnVar for a single DA step + using non-diagonal observation error covariance matrix. + + Here, the background error covariance is + hybridised by a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + LESTKF in this implementation. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + 4. The iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core DA algorithm + 5. py__cvt_pdaf + 6. py__cvt_ens_pdaf + 7. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__prodRinvA_l_pdaf + 4. core DA algorithm + 8. py__prepoststep_state_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A and apply localizations + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__next_observation_pdaf : Callable + Provide information on next forecast + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + +def generate_obs(py__collect_state_pdaf:Callable, py__distribute_state_pdaf:Callable, + py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, py__get_obs_f_pdaf:Callable, + py__prepoststep_pdaf:Callable, py__next_observation_pdaf:Callable, outflag:int) -> int: + """Generation of synthetic observations based on + given error statistics and observation operator. + + The generated synthetic observations are based on + each member of model forecast. + Therefore, an ensemble of observations can be obtained. + In a typical experiment, + one may only need one ensemble member. + The implementation strategy is similar to + an assimilation step. This means that, + one can reuse many user-supplied functions for + assimilation and observation generation. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__get_obs_f_pdaf + 6. py__prepoststep_state_pdaf + 7. py__distribute_state_pdaf + 8. py__next_observation_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__get_obs_f_pdaf : Callable + Initialize observation vector + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + +def generate_obs_offline(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, + py__get_obs_f_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int: + """Generation of synthetic observations based on + given error statistics and observation operator in offline setup. + + The generated synthetic observations are based on + each member of model forecast. + Therefore, an ensemble of observations can be obtained. + In a typical experiment, + one may only need one ensemble member. + The implementation strategy is similar to + an assimilation step. This means that, + one can reuse many user-supplied functions for + assimilation and observation generation. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + 4. py__get_obs_f_pdaf + 5. py__prepoststep_state_pdaf + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__get_obs_f_pdaf : Callable + Initialize observation vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ diff --git a/pyPDAF/source/src/pyPDAF/PDAF3/assim.pyx b/pyPDAF/source/src/pyPDAF/PDAF3/assim.pyx new file mode 100644 index 0000000000000000000000000000000000000000..57b14572447895d836af425663ea0334d9ec2e73 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF3/assim.pyx @@ -0,0 +1,4809 @@ +import numpy as np +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb + + +def assimilate(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf, int outflag): + r"""assimilate(py__collect_state_pdaf:Callable, py__distribute_state_pdaf:Callable, py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, py__init_n_domains_p_pdaf:Callable, py__init_dim_l_pdaf:Callable, py__init_dim_obs_l_pdaf:Callable, py__prepoststep_pdaf:Callable, py__next_observation_pdaf:Callable, outflag:int) -> int + + Online ensemble filters and smoothers except for 3DVars for a single DA step + using diagnoal observation error covariance matrix. + + Here, this function call is used for + global stochastic EnKF [1]_, E(S)TKF [2]_, EAKF, EnSRF, + SEEK [2]_, SEIK [2]_, NETF [3]_, and particle filter [4]_. + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. core DA algorithm + 7. py__prepoststep_state_pdaf + 8. py__distribute_state_pdaf + 9. py__next_observation_pdaf + + References + ---------- + .. [1] Evensen, G. (1994), + Sequential data assimilation with + a nonlinear quasi-geostrophic model + using Monte Carlo methods to forecast error statistics, + J. Geophys. Res., 99(C5), 10143–10162, doi:10.1029/94JC00572. + .. [2] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + .. [3] Tödter, J., and B. Ahrens, 2015: + A second-order exact ensemble square root filter + for nonlinear data assimilation. Mon. Wea. Rev., + 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1. + .. [4] Van Leeuwen, P. J., Künsch, H. R., Nerger, L., + Potthast, R., & Reich, S. (2019). + Particle filters for high‐dimensional geoscience applications: + A review. Quarterly Journal of the Royal Meteorological Society, 145(723), 2335-2365. + + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaf3_assimilate(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assim_offline(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prepoststep_pdaf, int outflag): + r"""assim_offline(py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, py__init_n_domains_p_pdaf: Callable, py__init_dim_l_pdaf: Callable, py__init_dim_obs_l_pdaf: Callable, py__prepoststep_pdaf: Callable, outflag:int) -> int + + Offline ensemble filters and smoothers except for 3DVars for a single DA step + using diagnoal observation error covariance matrix. + + Here, this function call is used for + global stochastic EnKF [1]_, E(S)TKF [2]_, EAKF, EnSRF, + SEEK [2]_, SEIK [2]_, NETF [3]_, and particle filter [4]_. + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_n_domains_p_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. core DA algorithm + 6. py__prepoststep_state_pdaf + + + References + ---------- + .. [1] Evensen, G. (1994), + Sequential data assimilation with + a nonlinear quasi-geostrophic model + using Monte Carlo methods to forecast error statistics, + J. Geophys. Res., 99(C5), 10143–10162, doi:10.1029/94JC00572. + .. [2] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + .. [3] Tödter, J., and B. Ahrens, 2015: + A second-order exact ensemble square root filter + for nonlinear data assimilation. Mon. Wea. Rev., + 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1. + .. [4] Van Leeuwen, P. J., Künsch, H. R., Nerger, L., + Potthast, R., & Reich, S. (2019). + Particle filters for high‐dimensional geoscience applications: + A review. Quarterly Journal of the Royal Meteorological Society, 145(723), 2335-2365. + + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + with nogil: + c__pdaf3_assim_offline(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def assimilate_3dvar_all(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf, int outflag): + r"""assimilate_3dvar_all(py__collect_state_pdaf: Callable, py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, py__cvt_ens_pdaf: Callable, py__cvt_adj_ens_pdaf: Callable, py__cvt_pdaf: Callable, py__cvt_adj_pdaf: Callable, py__obs_op_lin_pdaf: Callable, py__obs_op_adj_pdaf: Callable, py__init_n_domains_p_pdaf: Callable, py__init_dim_l_pdaf: Callable, py__init_dim_obs_l_pdaf: Callable, py__prepoststep_pdaf: Callable, py__next_observation_pdaf: Callable, outflag:int) -> int + + Online assimilation for all types of 3DVar DA for a single DA step + using diagonal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assimilate_3dvar_nondiagR`, + :func:`pyPDAF.PDAF3.assimilate_en3dvar_lestkf_nondiagR`, + :func:`pyPDAF.PDAF3.assimilate_en3dvar_estkf_nondiagR`, + :func:`pyPDAF.PDAF3.assimilate_hyb3dvar_lestkf_nondiagR`, + :func:`pyPDAF.PDAF3.assimilate_hyb3dvar_estkf_nondiagR` + for non-diagonal observation error covariance matrix. + + When 3DVar is used, the background error covariance matrix + has to be modelled for cotrol variable transformation. + This is a deterministic filtering scheme + so no ensemble and parallelisation is needed. + This function should be called at each model time step. + + For parametrised 3DVar, user-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. Iterative optimisation: + 1. py__cvt_pdaf + 2. py__obs_op_lin_pdaf + 3. py__obs_op_adj_pdaf + 4. py__cvt_adj_pdaf + 5. core DA algorithm + 6. py__cvt_pdaf + 7. py__prepoststep_state_pdaf + 8. py__distribute_state_pdaf + 9. py__next_observation_pdaf + + For 3DEnVar, user-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. Starting the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__obs_op_adj_pdaf + 4. py__cvt_adj_ens_pdaf + 5. core DA algorithm + 6. py__cvt_ens_pdaf + 7. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. core DA algorithm + 8. py__prepoststep_state_pdaf + 9. py__distribute_state_pdaf + 10. py__next_observation_pdaf + + + For hybrid 3DVar, user-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. The iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_pdaf + 6. py__cvt_adj_ens_pdaf + 7. core DA algorithm + 6. py__cvt_pdaf + 7. py__cvt_ens_pdaf + 8. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. core DA algorithm + 9. py__prepoststep_state_pdaf + 10. py__distribute_state_pdaf + 11. py__next_observation_pdaf + + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + py__obs_op_lin_pdaf : Callable + Linearized observation operator + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaf3_assimilate_3dvar_all(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + +def assim_offline_3dvar_all(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__prepoststep_pdaf): + r"""assim_offline_3dvar_all(py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, py__cvt_ens_pdaf: Callable, py__cvt_adj_ens_pdaf: Callable, py__cvt_pdaf: Callable, py__cvt_adj_pdaf: Callable, py__obs_op_lin_pdaf: Callable, py__obs_op_adj_pdaf: Callable, py__init_n_domains_p_pdaf: Callable, py__init_dim_l_pdaf: Callable, py__init_dim_obs_l_pdaf: Callable, py__prepoststep_pdaf: Callable) -> int + + Offline assimilation for all types of 3DVar DA for a single DA step + using diagonal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.put_state_3dvar_nondiagR`, + :func:`pyPDAF.PDAF3.put_state_en3dvar_lestkf_nondiagR`, + :func:`pyPDAF.PDAF3.put_state_en3dvar_estkf_nondiagR`, + :func:`pyPDAF.PDAF3.put_state_hyb3dvar_lestkf_nondiagR`, + :func:`pyPDAF.PDAF3.put_state_hyb3dvar_estkf_nondiagR` + for non-diagonal observation error covariance matrix. + + When 3DVar is used, the background error covariance matrix + has to be modelled for cotrol variable transformation. + This is a deterministic filtering scheme + so no ensemble and parallelisation is needed. + This function should be called at each model time step. + + For parametrised 3DVar, user-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + 4. Iterative optimisation: + 1. py__cvt_pdaf + 2. py__obs_op_lin_pdaf + 3. py__obs_op_adj_pdaf + 4. py__cvt_adj_pdaf + 5. core DA algorithm + 5. py__cvt_pdaf + 6. py__prepoststep_state_pdaf + + For 3DEnVar, user-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + 4. Starting the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__obs_op_adj_pdaf + 4. py__cvt_adj_ens_pdaf + 5. core DA algorithm + 5. py__cvt_ens_pdaf + 6. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. core DA algorithm + 7. py__prepoststep_state_pdaf + + + For hybrid 3DVar, user-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + 4. The iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_pdaf + 6. py__cvt_adj_ens_pdaf + 7. core DA algorithm + 5. py__cvt_pdaf + 6. py__cvt_ens_pdaf + 7. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. core DA algorithm + 8. py__prepoststep_state_pdaf + + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + py__obs_op_lin_pdaf : Callable + Linearized observation operator + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_assim_offline_3dvar_all(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + +def assimilate_local_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prodrinva_l_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf, int outflag): + r"""assimilate_local_nondiagr(py__collect_state_pdaf: Callable, py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, py__init_n_domains_p_pdaf: Callable, py__init_dim_l_pdaf: Callable, py__init_dim_obs_l_pdaf: Callable, py__prodrinva_l_pdaf: Callable, py__prepoststep_pdaf: Callable, py__next_observation_pdaf: Callable, outflag: int) -> int + + Online assimilation of domain local filters for a single DA step + using non-diagnoal observation error covariance matrix. + + Here, this function call is used for LE(S)TKF [1]_ and LSEIK [1]_ + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__init_obs_l_pdaf + 4. py__prodRinvA_l_pdaf + 5. core DA algorithm + 7. py__prepoststep_state_pdaf + 8. py__distribute_state_pdaf + 9. py__next_observation_pdaf + + References + ---------- + .. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + py__prodrinva_l_pdaf : Callable + Provide product of inverse of R with matrix A + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaf3_assimilate_local_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_global_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prodrinva_pdaf, py__prepoststep_pdaf, py__next_observation_pdaf): + r"""assimilate_global_nondiagr(py__collect_state_pdaf: Callable, py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, py__prodrinva_pdaf: Callable, py__prepoststep_pdaf: Callable, py__next_observation_pdaf: Callable) -> int + + Online assimilation of global filters except for 3DVar and stochastic EnKF + for a single DA step using non-diagnoal observation + error covariance matrix. + + See :func:`pyPDAF.PDAF3.assimilate` + for diagonal observation error covariance matrix. + + Here, this function call is used for global, E(S)TKF [1]_, + SEIK [1]_. + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for ensemble mean) + 5. py__obs_op_pdaf (for each ensemble member) + 6. py__prodRinvA_pdaf + 7. core DA algorithm + 8. py__prepoststep_state_pdaf + 9. py__distribute_state_pdaf + 10. py__next_observation_pdaf + + References + ---------- + .. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__prodrinva_pdaf : Callable + Provide product of inverse of R with matrix A + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf3_assimilate_global_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_lnetf_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__likelihood_l_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf, int outflag): + r"""assimilate_lnetf_nondiagr(py__collect_state_pdaf: Callable, py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, py__init_n_domains_p_pdaf: Callable, py__init_dim_l_pdaf: Callable, py__init_dim_obs_l_pdaf: Callable, py__likelihood_l_pdaf: Callable, py__prepoststep_pdaf: Callable, py__next_observation_pdaf: Callable, outflag:int) -> int + + Online assimilation of LNETF for a single DA step using + non-diagnoal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assimilate` for + using diagnoal observation error covariance matrix. + The non-linear filter is proposed in [1]_. + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__likelihood_l_pdaf + 4. core DA algorithm + 7. py__prepoststep_state_pdaf + 8. py__distribute_state_pdaf + 9. py__next_observation_pdaf + + References + ---------- + .. [1] Tödter, J., and B. Ahrens, 2015: + A second-order exact ensemble square root filter + for nonlinear data assimilation. Mon. Wea. Rev., + 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + py__likelihood_l_pdaf : Callable + Compute likelihood and apply localization + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaf3_assimilate_lnetf_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_lknetf_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prodrinva_l_pdaf, + py__prodrinva_hyb_l_pdaf, py__likelihood_l_pdaf, + py__likelihood_hyb_l_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf, int outflag): + r"""assimilate_lknetf_nondiagr(py__collect_state_pdaf: Callable, py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, py__init_n_domains_p_pdaf: Callable, py__init_dim_l_pdaf: Callable, py__init_dim_obs_l_pdaf: Callable, py__prodrinva_l_pdaf: Callable, py__prodrinva_hyb_l_pdaf: Callable, py__likelihood_l_pdaf: Callable, py__likelihood_hyb_l_pdaf: Callable, py__prepoststep_pdaf: Callable, py__next_observation_pdaf: Callable, outflag: int) -> int + + Online assimilation of LKNETF for a single DA step using + non-diagonal observation error covariance matrix. + + + PDAFlocal-OMI modules require fewer user-supplied + functions and improved efficiency. + + LKNETF [1]_ for a single DA step using non-diagnoal + observation error covariance matrix. + See :func:`pyPDAF.PDAF3.assimilate` + for using diagnoal observation error covariance matrix. + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__prodRinvA_pdaf + 4. py__likelihood_l_pdaf + 5. core DA algorithm + 6. py__obs_op_pdaf + (only called with `HKN` and `HNK` options + called for each ensemble member) + 7. py__likelihood_hyb_l_pdaf + 8. py__prodRinvA_hyb_l_pdaf + 7. py__prepoststep_state_pdaf + 8. py__distribute_state_pdaf + 9. py__next_observation_pdaf + + References + ---------- + .. [1] Nerger, L.. (2022) + Data assimilation for nonlinear systems with + a hybrid nonlinear Kalman ensemble transform filter. + Q J R Meteorol Soc, 620–640. doi:10.1002/qj.4221 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + py__prodrinva_l_pdaf : Callable + Provide product of inverse of R with matrix A + py__prodrinva_hyb_l_pdaf : Callable + Product R^-1 A on local analysis domain with hybrid weight + py__likelihood_l_pdaf : Callable + Compute likelihood and apply localization + py__likelihood_hyb_l_pdaf : Callable + Compute likelihood and apply localization with tempering + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.prodrinva_hyb_l_pdaf = py__prodrinva_hyb_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.likelihood_hyb_l_pdaf = py__likelihood_hyb_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaf3_assimilate_lknetf_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__prodrinva_hyb_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__likelihood_hyb_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_enkf_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__add_obs_err_pdaf, py__init_obs_covar_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf): + r"""assimilate_enkf_nondiagr(py__collect_state_pdaf: Callable, py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, py__add_obs_err_pdaf: Callable, py__init_obs_covar_pdaf: Callable, py__prepoststep_pdaf: Callable, py__next_observation_pdaf: Callable) -> int + + Online assimilation of global or Covariance localised stochastic EnKF + for a single DA step using non-diagonal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assimilate` + for diagonal observation error covariance matrix. + + This stochastic EnKF is implemented based on [1]_ + + This is the only scheme for covariance localisation with non-diagonal + observation error covariance matrix in PDAF. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. py__localize_pdaf + 6. py__add_obs_err_pdaf + 7. py__init_obscovar_pdaf + 8. py__obs_op_pdaf (repeated to reduce storage) + 9. core DA algorith + 10. py__prepoststep_state_pdaf + 11. py__distribute_state_pdaf + 12. py__next_observation_pdaf + + References + ---------- + .. [1] Houtekamer, P. L., and H. L. Mitchell (1998): + Data Assimilation Using an Ensemble Kalman Filter Technique. + Mon. Wea. Rev., 126, 796–811, + doi: 10.1175/1520-0493(1998)126<0796:DAUAEK>2.0.CO;2. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__add_obs_err_pdaf : Callable + Add observation error covariance matrix + py__init_obs_covar_pdaf : Callable + Initialize mean observation error variance + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf3_assimilate_enkf_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_lenkf_nondiagr(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__localize_covar_pdaf, py__add_obs_err_pdaf, py__init_obs_covar_pdaf, + py__prepoststep_pdaf, py__next_observation_pdaf): + r"""assimilate_lenkf_nondiagr(py__collect_state_pdaf: Callable, py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, py__localize_covar_pdaf: Callable, py__add_obs_err_pdaf: Callable, py__init_obs_covar_pdaf: Callable, py__prepoststep_pdaf: Callable, py__next_observation_pdaf: Callable) -> int + + Covariance localised stochastic EnKF + for a single DA step using non-diagnoal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assimilate` or :func:`pyPDAF.PDAF3.assim_offline` + for diagnoal observation error covariance matrix. + + This stochastic EnKF is implemented based on [1]_ + + This is the only scheme for covariance localisation with non-diagonal + observation error covariance matrix in PDAF. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. py__localize_pdaf + 6. py__add_obs_err_pdaf + 7. py__init_obscovar_pdaf + 8. py__obs_op_pdaf (repeated to reduce storage) + 9. core DA algorith + 10. py__prepoststep_state_pdaf + 11. py__distribute_state_pdaf + 12. py__next_observation_pdaf + + References + ---------- + .. [1] Houtekamer, P. L., and H. L. Mitchell (1998): + Data Assimilation Using an Ensemble Kalman Filter Technique. + Mon. Wea. Rev., 126, 796–811, + doi: 10.1175/1520-0493(1998)126<0796:DAUAEK>2.0.CO;2. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__localize_covar_pdaf : Callable + Apply covariance localization + py__add_obs_err_pdaf : Callable + Add observation error covariance matrix + py__init_obs_covar_pdaf : Callable + Initialize mean observation error variance + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.localize_covar_pdaf = py__localize_covar_pdaf + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf3_assimilate_lenkf_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__localize_covar_pdaf, + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_nonlin_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__likelihood_pdaf, py__prepoststep_pdaf, py__next_observation_pdaf): + r"""assimilate_nonlin_nondiagr(py__collect_state_pdaf: Callable, py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, py__likelihood_pdaf: Callable, py__prepoststep_pdaf: Callable, py__next_observation_pdaf: Callable) -> int + + Online assimilation of global nonlinear filters for a single DA step + using non-diagonal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assimilate` + for diagonal observation error covariance matrix. + + Here, this function call is used for global NETF [1]_, + and particle filter [2]_. + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR` and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for ensemble mean) + 5. py__obs_op_pdaf (for each ensemble member) + 6. py__likelihood_pdaf + 7. core DA algorithm + 8. py__prepoststep_state_pdaf + 9. py__distribute_state_pdaf + 10. py__next_observation_pdaf + + References + ---------- + .. [1] Tödter, J., and B. Ahrens, 2015: + A second-order exact ensemble square root filter + for nonlinear data assimilation. Mon. Wea. Rev., + 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1. + .. [2] Van Leeuwen, P. J., Künsch, H. R., Nerger, L., + Potthast, R., & Reich, S. (2019). + Particle filters for high‐dimensional geoscience applications: + A review. Quarterly Journal of the Royal Meteorological Society, 145(723), 2335-2365. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__likelihood_pdaf : Callable + Compute likelihood + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.likelihood_pdaf = py__likelihood_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf3_assimilate_nonlin_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__likelihood_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + + + + + + + +def assimilate_3dvar_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prodrinva_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf): + r"""assimilate_3dvar_nondiagr(py__collect_state_pdaf: Callable, py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, py__prodrinva_pdaf: Callable, py__cvt_pdaf: Callable, py__cvt_adj_pdaf: Callable, py__obs_op_lin_pdaf: Callable, py__obs_op_adj_pdaf: Callable, py__prepoststep_pdaf: Callable, py__next_observation_pdaf: Callable) -> int + + 3DVar DA for a single DA step + using non-diagnoal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assimilate_3dvar_all` + for diagonal observation error covariance matrix. + + When 3DVar is used, the background error covariance matrix + has to be modelled for cotrol variable transformation. + This is a deterministic filtering scheme + so no ensemble and parallelisation is needed. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. Iterative optimisation: + 1. py__cvt_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_pdaf + 6. core DA algorithm + 6. py__cvt_pdaf + 7. py__prepoststep_state_pdaf + 8. py__distribute_state_pdaf + 9. py__next_observation_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__prodrinva_pdaf : Callable + Provide product R^-1 A + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + py__obs_op_lin_pdaf : Callable + Linearized observation operator + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf3_assimilate_3dvar_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_en3dvar_estkf_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prodrinva_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf): + r"""assimilate_en3dvar_estkf_nondiagr(py__collect_state_pdaf: Callable, py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, py__prodrinva_pdaf: Callable, py__cvt_ens_pdaf: Callable, py__cvt_adj_ens_pdaf: Callable, py__obs_op_lin_pdaf: Callable, py__obs_op_adj_pdaf: Callable, py__prepoststep_pdaf: Callable, py__next_observation_pdaf: Callable) -> int + + 3DEnVar for a single DA step + using non-diagnoal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assimilate_3dvar_all` + for diagonal observation error covariance matirx. + + Here, the background error covariance matrix is + estimated by an ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An ESTKF is used along with 3DEnVar to generate ensemble perturbations. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core 3DEnVar algorithm + 6. py__cvt_ens_pdaf + 7. ESTKF: + 1. py__init_dim_obs_pdaf + 2. py__obs_op_pdaf (for ensemble mean) + 3. py__obs_op_pdaf (for each ensemble member) + 4. py__prodRinvA_pdaf + 5. core ESTKF algorithm + 8. py__prepoststep_state_pdaf + 9. py__distribute_state_pdaf + 10. py__next_observation_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__prodrinva_pdaf : Callable + Provide product R^-1 A + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + py__obs_op_lin_pdaf : Callable + Linearized observation operator + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf3_assimilate_en3dvar_estkf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_en3dvar_lestkf_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prodrinva_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prodrinva_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf, int outflag): + r"""assimilate_en3dvar_lestkf_nondiagr(py__collect_state_pdaf: Callable, py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, py__prodrinva_pdaf: Callable, py__cvt_ens_pdaf: Callable, py__cvt_adj_ens_pdaf: Callable, py__obs_op_lin_pdaf: Callable, py__obs_op_adj_pdaf: Callable, py__prodrinva_l_pdaf: Callable, py__init_n_domains_p_pdaf: Callable, py__init_dim_l_pdaf: Callable, py__init_dim_obs_l_pdaf: Callable, py__prepoststep_pdaf: Callable, py__next_observation_pdaf:Callable, outflag:int) -> int + + 3DEnVar for a single DA step where the ensemble anomaly + is generated by LESTKF using non-diagonal observation + error covariance matrix. + + PDAFlocal-OMI modules require fewer user-supplied + functions and improved efficiency. + + 3DEnVar for a single DA step where the ensemble anomaly + is generated by LESTKF + using non-diagnoal observation error covariance matrix. + The background error covariance matrix is estimated by ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An LESTKF is used to generate ensemble perturbations. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. Starting the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core DA algorithm + 6. py__cvt_ens_pdaf + 7. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__prodRinvA_l_pdaf + 4. core DA algorithm + 8. py__prepoststep_state_pdaf + 9. py__distribute_state_pdaf + 10. py__next_observation_pdaf + + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__prodrinva_pdaf : Callable + Provide product R^-1 A + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + py__obs_op_lin_pdaf : Callable + Linearized observation operator + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A and apply localizations + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaf3_assimilate_en3dvar_lestkf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_hyb3dvar_estkf_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prodrinva_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__cvt_pdaf, py__cvt_adj_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__prepoststep_pdaf, py__next_observation_pdaf): + r"""assimilate_hyb3dvar_estkf_nondiagr(py__collect_state_pdaf: Callable, py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, py__prodrinva_pdaf: Callable, py__cvt_ens_pdaf: Callable, py__cvt_adj_ens_pdaf: Callable, py__cvt_pdaf: Callable, py__cvt_adj_pdaf: Callable, py__obs_op_lin_pdaf: Callable, py__obs_op_adj_pdaf: Callable, py__prepoststep_pdaf: Callable, py__next_observation_pdaf: Callable) -> int + + Hybrid 3DEnVar for a single DA step + using non-diagnoal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assimilate_3dvar_all` + for diagonal observation error covariance matrix. + + Here the background error covariance is hybridised by + a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + ESTKF in this implementation. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. the iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core 3DEnVar algorithm + 6. py__cvt_pdaf + 7. py__cvt_ens_pdaf + 8. Perform ESTKF: + 1. py__init_dim_obs_pdaf + 2. py__obs_op_pdaf + (for ensemble mean) + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__prodRinvA_pdaf + 5. core ESTKF algorithm + 9. py__prepoststep_state_pdaf + 10. py__distribute_state_pdaf + 11. py__next_observation_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__prodrinva_pdaf : Callable + Provide product R^-1 A + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + py__obs_op_lin_pdaf : Callable + Linearized observation operator + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf3_assimilate_hyb3dvar_estkf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_hyb3dvar_lestkf_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prodrinva_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__cvt_pdaf, py__cvt_adj_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf, int outflag): + r"""assimilate_hyb3dvar_lestkf_nondiagr(py__collect_state_pdaf: Callable, py__distribute_state_pdaf: Callable, py__init_dim_obs_pdaf: Callable, py__obs_op_pdaf: Callable, py__prodrinva_pdaf: Callable, py__cvt_ens_pdaf: Callable, py__cvt_adj_ens_pdaf: Callable, py__cvt_pdaf: Callable, py__cvt_adj_pdaf: Callable, py__obs_op_lin_pdaf: Callable, py__obs_op_adj_pdaf: Callable, py__prodrinva_l_pdaf: Callable, py__init_n_domains_p_pdaf: Callable, py__init_dim_l_pdaf: Callable, py__init_dim_obs_l_pdaf: Callable, py__prepoststep_pdaf: Callable, py__next_observation_pdaf: Callable, outflag:int) -> int + + Hybrid 3DEnVar for a single DA step + using non-diagonal observation error covariance matrix. + + Here, the background error covariance is + hybridised by a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + LESTKF in this implementation. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. The iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core DA algorithm + 6. py__cvt_pdaf + 7. py__cvt_ens_pdaf + 8. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__prodRinvA_l_pdaf + 4. core DA algorithm + 9. py__prepoststep_state_pdaf + 10. py__distribute_state_pdaf + 11. py__next_observation_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A and apply localizations + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__next_observation_pdaf : Callable + Provide information on next forecast + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaf3_assimilate_hyb3dvar_lestkf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + + + + + + +def assim_offline_local_nondiagr(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prodrinva_l_pdaf, py__prepoststep_pdaf): + r"""assim_offline_local_nondiagr(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, py__init_n_domains_p_pdaf:Callable, py__init_dim_l_pdaf:Callable, py__init_dim_obs_l_pdaf:Callable, py__prodrinva_l_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int + + Offline assimilation of domain local filters for a single DA step + using non-diagnoal observation error covariance matrix. + + Here, this function call is used for LE(S)TKF [1]_ and LSEIK [1]_ + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_n_domains_p_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__init_obs_l_pdaf + 4. py__prodRinvA_l_pdaf + 5. core DA algorithm + 6. py__prepoststep_state_pdaf + + References + ---------- + .. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prodrinva_l_pdaf : Callable + Provide product of inverse of R with matrix A + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_assim_offline_local_nondiagr(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def assim_offline_global_nondiagr(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prodrinva_pdaf, py__prepoststep_pdaf): + r"""assim_offline_global_nondiagr(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, py__prodrinva_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int + + Offline assimilation of global filters except for 3DVar and stochastic EnKF + for a single DA step using non-diagnoal observation + error covariance matrix. + + See :func:`pyPDAF.PDAF3.assimilate` + for diagonal observation error covariance matrix. + + Here, this function call is used for global, E(S)TKF [1]_, + SEIK [1]_. + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf (for ensemble mean) + 4. py__obs_op_pdaf (for each ensemble member) + 5. py__prodRinvA_pdaf + 6. core DA algorithm + 7. py__prepoststep_state_pdaf + + References + ---------- + .. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prodrinva_pdaf : Callable + Provide product of inverse of R with matrix A + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_assim_offline_global_nondiagr( + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def assim_offline_lnetf_nondiagr(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__likelihood_l_pdaf, py__prepoststep_pdaf): + r"""assim_offline_lnetf_nondiagr(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, py__init_n_domains_p_pdaf:Callable, py__init_dim_l_pdaf:Callable, py__init_dim_obs_l_pdaf:Callable, py__likelihood_l_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int + + Offline assimilation of LNETF for a single DA step using + non-diagnoal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assim_offline` for + using diagnoal observation error covariance matrix. + The non-linear filter is proposed in [1]_. + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_n_domains_p_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__likelihood_l_pdaf + 4. core DA algorithm + 6. py__prepoststep_state_pdaf + + References + ---------- + .. [1] Tödter, J., and B. Ahrens, 2015: + A second-order exact ensemble square root filter + for nonlinear data assimilation. Mon. Wea. Rev., + 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__likelihood_l_pdaf : Callable + Compute likelihood and apply localization + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + cdef int outflag + with nogil: + c__pdaf3_assim_offline_lnetf_nondiagr(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def assim_offline_lknetf_nondiagr(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prodrinva_l_pdaf, + py__prodrinva_hyb_l_pdaf, py__likelihood_l_pdaf, py__likelihood_hyb_l_pdaf, + py__prepoststep_pdaf): + r"""assim_offline_lknetf_nondiagr(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, py__init_n_domains_p_pdaf:Callable, py__init_dim_l_pdaf:Callable, py__init_dim_obs_l_pdaf:Callable, py__prodrinva_l_pdaf:Callable, py__prodrinva_hyb_l_pdaf:Callable, py__likelihood_l_pdaf:Callable, py__likelihood_hyb_l_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int + + Offline assimilation of LKNETF for a single DA step using + non-diagonal observation error covariance matrix. + + + PDAFlocal-OMI modules require fewer user-supplied + functions and improved efficiency. + + LKNETF [1]_ for a single DA step using non-diagnoal + observation error covariance matrix. + See :func:`pyPDAF.PDAF3.assimilate` + for using diagnoal observation error covariance matrix. + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_n_domains_p_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__prodRinvA_pdaf + 4. py__likelihood_l_pdaf + 5. core DA algorithm + 6. py__obs_op_pdaf + (only called with `HKN` and `HNK` options + called for each ensemble member) + 7. py__likelihood_hyb_l_pdaf + 8. py__prodRinvA_hyb_l_pdaf + 6. py__prepoststep_state_pdaf + + References + ---------- + .. [1] Nerger, L.. (2022) + Data assimilation for nonlinear systems with + a hybrid nonlinear Kalman ensemble transform filter. + Q J R Meteorol Soc, 620–640. doi:10.1002/qj.4221 + + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prodrinva_l_pdaf : Callable + Provide product of inverse of R with matrix A + + py__prodrinva_hyb_l_pdaf : Callable + Product R^-1 A on local analysis domain with hybrid weight + + py__likelihood_l_pdaf : Callable + Compute likelihood and apply localization + + py__likelihood_hyb_l_pdaf : Callable + Compute likelihood and apply localization with tempering + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.prodrinva_hyb_l_pdaf = py__prodrinva_hyb_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.likelihood_hyb_l_pdaf = py__likelihood_hyb_l_pdaf + cdef int outflag + with nogil: + c__pdaf3_assim_offline_lknetf_nondiagr( + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__prodrinva_hyb_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__likelihood_hyb_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def assim_offline_enkf_nondiagr(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__add_obs_err_pdaf, py__init_obs_covar_pdaf, py__prepoststep_pdaf): + r"""assim_offline_enkf_nondiagr(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, py__add_obs_err_pdaf:Callable, py__init_obs_covar_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int + + Offline assimilation of global or Covariance localised stochastic EnKF + for a single DA step using non-diagonal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assim_offline` + for diagonal observation error covariance matrix. + + This stochastic EnKF is implemented based on [1]_ + + This is the only scheme for covariance localisation with non-diagonal + observation error covariance matrix in PDAF. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf (for each ensemble member) + 4. py__localize_pdaf + 5. py__add_obs_err_pdaf + 6. py__init_obscovar_pdaf + 7. py__obs_op_pdaf (repeated to reduce storage) + 8. core DA algorithm + 9. py__prepoststep_state_pdaf + + References + ---------- + .. [1] Houtekamer, P. L., and H. L. Mitchell (1998): + Data Assimilation Using an Ensemble Kalman Filter Technique. + Mon. Wea. Rev., 126, 796–811, + doi: 10.1175/1520-0493(1998)126<0796:DAUAEK>2.0.CO;2. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__add_obs_err_pdaf : Callable + Add observation error covariance matrix + + py__init_obs_covar_pdaf : Callable + Initialize mean observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_assim_offline_enkf_nondiagr(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def assim_offline_lenkf_nondiagr(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__localize_covar_pdaf, py__add_obs_err_pdaf, + py__init_obs_covar_pdaf, py__prepoststep_pdaf): + r"""assim_offline_lenkf_nondiagr(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, py__localize_covar_pdaf:Callable, py__add_obs_err_pdaf:Callable, py__init_obs_covar_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int + + Online assimilation of covariance localised stochastic EnKF + for a single DA step using non-diagonal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assim_offline` + for diagonal observation error covariance matrix. + + This stochastic EnKF is implemented based on [1]_ + + This is the only scheme for covariance localisation with non-diagonal + observation error covariance matrix in PDAF. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf (for each ensemble member) + 4. py__localize_pdaf + 5. py__add_obs_err_pdaf + 6. py__init_obscovar_pdaf + 7. py__obs_op_pdaf (repeated to reduce storage) + 8. core DA algorithm + 9. py__prepoststep_state_pdaf + + References + ---------- + .. [1] Houtekamer, P. L., and H. L. Mitchell (1998): + Data Assimilation Using an Ensemble Kalman Filter Technique. + Mon. Wea. Rev., 126, 796–811, + doi: 10.1175/1520-0493(1998)126<0796:DAUAEK>2.0.CO;2. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__localize_covar_pdaf : Callable + Apply covariance localization + + py__add_obs_err_pdaf : Callable + Add observation error covariance matrix + + py__init_obs_covar_pdaf : Callable + Initialize mean observation error variance + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.localize_covar_pdaf = py__localize_covar_pdaf + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + cdef int outflag + with nogil: + c__pdaf3_assim_offline_lenkf_nondiagr(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__localize_covar_pdaf, + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def assim_offline_nonlin_nondiagr(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__likelihood_pdaf, py__prepoststep_pdaf): + r"""assim_offline_nonlin_nondiagr(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, py__likelihood_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int + + Offline assimilation of global nonlinear filters for a single DA step + using non-diagonal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assim_offline` + for diagonal observation error covariance matrix. + + Here, this function call is used for global NETF [1]_, + and particle filter [2]_. + The filter type is set in :func:`pyPDAF.PDAF.init`. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR` and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf (for ensemble mean) + 4. py__obs_op_pdaf (for each ensemble member) + 5. py__likelihood_pdaf + 6. core DA algorithm + 7. py__prepoststep_state_pdaf + + References + ---------- + .. [1] Tödter, J., and B. Ahrens, 2015: + A second-order exact ensemble square root filter + for nonlinear data assimilation. Mon. Wea. Rev., + 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1. + .. [2] Van Leeuwen, P. J., Künsch, H. R., Nerger, L., + Potthast, R., & Reich, S. (2019). + Particle filters for high‐dimensional geoscience applications: + A review. Quarterly Journal of the Royal Meteorological Society, 145(723), 2335-2365. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__likelihood_pdaf : Callable + Compute likelihood + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.likelihood_pdaf = py__likelihood_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_assim_offline_nonlin_nondiagr( + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__likelihood_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + + + + +def assimilate_3dvar(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf): + """It is recommended to use :func:`pyPDAF.PDAF3.assimilate_3dvar_all` + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + 3DVar DA for a single step without OMI. + When 3DVar is used, the background error covariance matrix + has to be modelled for cotrol variable + transformation. This is a deterministic filtering + scheme so no ensemble and + parallelisation is needed. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_3dvar` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. Iterative optimisation: + 1. py__cvt_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_pdaf + 6. core DA algorithm + 7. py__cvt_pdaf + 8. py__prepoststep_state_pdaf + 9. py__distribute_state_pdaf + 10. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by :func:`pyPDAF.PDAF.omi_assimilate_3dvar` + and :func:`pyPDAF.PDAF.omi_assimilate_3dvar_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf3_assimilate_3dvar(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assimilate_en3dvar(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf, int outflag): + """It is recommended to use :func:`pyPDAF.PDAF3.assimilate_3dvar_all` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__next_observation_pdaf : Callable + Provide information on next forecast + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaf3_assimilate_en3dvar(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assimilate_en3dvar_estkf(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__prepoststep_pdaf, py__next_observation_pdaf): + """It is recommended to use :func:`pyPDAF.PDAF3.assimilate_3dvar_all` + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + 3DEnVar for a single DA step. + The background error covariance matrix is estimated + by an ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An ESTKF is used along with 3DEnVar + to generate ensemble perturbations. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_en3dvar_estkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core 3DEnVar algorithm + 7. py__cvt_ens_pdaf + 8. ESTKF: + 1. py__init_dim_obs_pdaf + 2. py__obs_op_pdaf (for ensemble mean) + 3. py__init_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. py__init_obsvar_pdaf + (only relevant for adaptive + forgetting factor schemes) + 6. py__prodRinvA_pdaf + 7. core ESTKF algorithm + 9. py__prepoststep_state_pdaf + 10. py__distribute_state_pdaf + 11. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_assimilate_en3dvar_estkf` + and :func:`pyPDAF.PDAF.omi_assimilate_en3dvar_estkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf3_assimilate_en3dvar_estkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_en3dvar_lestkf(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf, int outflag): + """It is recommended to use :func:`pyPDAF.PDAF3.assimilate_3dvar_all` + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + 3DEnVar for a single DA step where the ensemble anomaly + is generated by LESTKF. + The background error covariance matrix is + estimated by ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An LESTKF is used to generate ensemble perturbations. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_en3dvar_lestkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. Starting the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core DA algorithm + 7. py__cvt_ens_pdaf + 8. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__init_obs_pdaf + (if global adaptive forgetting factor is used + `type_forget=1` in :func:`pyPDAF.PDAF.init`) + 5. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise mean ensemble in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local + adaptive forgetting factor + `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + 9. py__prepoststep_state_pdaf + 10. py__distribute_state_pdaf + 11. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf` + and + :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__next_observation_pdaf : Callable + Provide information on next forecast + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaf3_assimilate_en3dvar_lestkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_hyb3dvar(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf, int outflag): + """It is recommended to use :func:`pyPDAF.PDAF3.assimilate_3dvar_all` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__next_observation_pdaf : Callable + Provide information on next forecast + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaf3_assimilate_hyb3dvar(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assimilate_hyb3dvar_estkf(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf): + """It is recommended to use :func:`pyPDAF.PDAF3.assimilate_3dvar_all` + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Hybrid 3DEnVar for a single DA step where + the background error covariance is hybridised by + a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + ESTKF in this implementation. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_hyb3dvar_estkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. the iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core 3DEnVar algorithm + 7. py__cvt_pdaf + 8. py__cvt_ens_pdaf + 9. Perform ESTKF: + 1. py__init_dim_obs_pdaf + 2. py__obs_op_pdaf + (for ensemble mean) + 3. py__init_obs_pdaf + 4. py__obs_op_pdaf + (for each ensemble member) + 5. py__init_obsvar_pdaf + (only relevant for adaptive + forgetting factor schemes) + 6. py__prodRinvA_pdaf + 7. core ESTKF algorithm + 10. py__prepoststep_state_pdaf + 11. py__distribute_state_pdaf + 12. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_assimilate_hyb3dvar_estkf` and + :func:`pyPDAF.PDAF.omi_assimilate_hyb3dvar_estkf_nondiagR`. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf3_assimilate_hyb3dvar_estkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_hyb3dvar_lestkf(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf, int outflag): + """It is recommended to use :func:`pyPDAF.PDAF3.assimilate_3dvar_all` + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Hybrid 3DEnVar for a single DA step where + the background error covariance is hybridised by + a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + LESTKF in this implementation. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_hyb3dvar_lestkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. The iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core DA algorithm + 7. py__cvt_pdaf + 8. py__cvt_ens_pdaf + 9. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__init_obs_pdaf + (if global adaptive forgetting factor + `type_forget=1` in :func:`pyPDAF.PDAF.init`) + 5. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise mean ensemble in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting + factor `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + 10. py__prepoststep_state_pdaf + 11. py__distribute_state_pdaf + 12. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf` + and + :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__next_observation_pdaf : Callable + Provide information on next forecast + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaf3_assimilate_hyb3dvar_lestkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def generate_obs(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__get_obs_f_pdaf, + py__prepoststep_pdaf, py__next_observation_pdaf, int outflag): + """generate_obs(py__collect_state_pdaf:Callable, py__distribute_state_pdaf:Callable, py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, py__get_obs_f_pdaf:Callable, py__prepoststep_pdaf:Callable, py__next_observation_pdaf:Callable, outflag:int) -> int + + Generation of synthetic observations based on + given error statistics and observation operator. + + The generated synthetic observations are based on + each member of model forecast. + Therefore, an ensemble of observations can be obtained. + In a typical experiment, + one may only need one ensemble member. + The implementation strategy is similar to + an assimilation step. This means that, + one can reuse many user-supplied functions for + assimilation and observation generation. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__get_obs_f_pdaf + 6. py__prepoststep_state_pdaf + 7. py__distribute_state_pdaf + 8. py__next_observation_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__get_obs_f_pdaf : Callable + Initialize observation vector + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.get_obs_f_pdaf = py__get_obs_f_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaf3_generate_obs(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__get_obs_f_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def generate_obs_offline(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__get_obs_f_pdaf, py__prepoststep_pdaf): + """generate_obs_offline(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, py__get_obs_f_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int + + Generation of synthetic observations based on + given error statistics and observation operator in offline setup. + + The generated synthetic observations are based on + each member of model forecast. + Therefore, an ensemble of observations can be obtained. + In a typical experiment, + one may only need one ensemble member. + The implementation strategy is similar to + an assimilation step. This means that, + one can reuse many user-supplied functions for + assimilation and observation generation. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + 4. py__get_obs_f_pdaf + 5. py__prepoststep_state_pdaf + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__get_obs_f_pdaf : Callable + Initialize observation vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.get_obs_f_pdaf = py__get_obs_f_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_generate_obs_offline(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__get_obs_f_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def assim_offline_3dvar(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__cvt_pdaf, py__cvt_adj_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_assim_offline_3dvar(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def assim_offline_en3dvar(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_assim_offline_en3dvar(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def assim_offline_en3dvar_estkf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_assim_offline_en3dvar_estkf(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def assim_offline_en3dvar_lestkf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_assim_offline_en3dvar_lestkf(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def assim_offline_hyb3dvar(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_assim_offline_hyb3dvar(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def assim_offline_hyb3dvar_estkf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_assim_offline_hyb3dvar_estkf(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def assim_offline_hyb3dvar_lestkf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_assim_offline_hyb3dvar_lestkf( + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def assim_offline_3dvar_nondiagr(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prodrinva_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prepoststep_pdaf): + r"""assim_offline_3dvar_nondiagr(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, py__prodrinva_pdaf:Callable, py__cvt_pdaf:Callable, py__cvt_adj_pdaf:Callable, py__obs_op_lin_pdaf:Callable, py__obs_op_adj_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int + + Offline 3DVar DA for a single DA step + using non-diagonal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assim_offline_3dvar_all` + for diagonal observation error covariance matrix. + + When 3DVar is used, the background error covariance matrix + has to be modelled for cotrol variable transformation. + This is a deterministic filtering scheme + so no ensemble and parallelisation is needed. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + 4. Iterative optimisation: + 1. py__cvt_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_pdaf + 6. core DA algorithm + 5. py__cvt_pdaf + 6. py__prepoststep_state_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__prodrinva_pdaf : Callable + Provide product R^-1 A + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + py__obs_op_lin_pdaf : Callable + Linearized observation operator + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_assim_offline_3dvar_nondiagr(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def assim_offline_en3dvar_estkf_nondiagr(py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__prodrinva_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, + py__prepoststep_pdaf): + r"""assim_offline_en3dvar_estkf_nondiagr(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, py__prodrinva_pdaf:Callable, py__cvt_ens_pdaf:Callable, py__cvt_adj_ens_pdaf:Callable, py__obs_op_lin_pdaf:Callable, py__obs_op_adj_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int + + Offline 3DEnVar for a single DA step + using non-diagonal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assim_offline_3dvar_all` + for diagonal observation error covariance matrix. + + Here, the background error covariance matrix is + estimated by an ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An ESTKF is used along with 3DEnVar to generate ensemble perturbations. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + 4. the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core 3DEnVar algorithm + 5. py__cvt_ens_pdaf + 6. ESTKF: + 1. py__init_dim_obs_pdaf + 2. py__obs_op_pdaf (for ensemble mean) + 3. py__obs_op_pdaf (for each ensemble member) + 4. py__prodRinvA_pdaf + 5. core ESTKF algorithm + 7. py__prepoststep_state_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__prodrinva_pdaf : Callable + Provide product R^-1 A + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + py__obs_op_lin_pdaf : Callable + Linearized observation operator + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_assim_offline_en3dvar_estkf_nondiagr( + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def assim_offline_en3dvar_lestkf_nondiagr(py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__prodrinva_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, + py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prepoststep_pdaf): + r"""assim_offline_en3dvar_lestkf_nondiagr(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, py__prodrinva_pdaf:Callable, py__cvt_ens_pdaf:Callable, py__cvt_adj_ens_pdaf:Callable, py__obs_op_lin_pdaf:Callable, py__obs_op_adj_pdaf:Callable, py__prodrinva_l_pdaf:Callable, py__init_n_domains_p_pdaf:Callable, py__init_dim_l_pdaf:Callable, py__init_dim_obs_l_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int + + Offline 3DEnVar for a single DA step where the ensemble anomaly + is generated by LESTKF using non-diagonal observation + error covariance matrix. + + PDAFlocal-OMI modules require fewer user-supplied + functions and improved efficiency. + + 3DEnVar for a single DA step where the ensemble anomaly + is generated by LESTKF + using non-diagnoal observation error covariance matrix. + The background error covariance matrix is estimated by ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An LESTKF is used to generate ensemble perturbations. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + 4. Starting the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core DA algorithm + 5. py__cvt_ens_pdaf + 6. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__prodRinvA_l_pdaf + 4. core DA algorithm + 7. py__prepoststep_state_pdaf + + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__prodrinva_pdaf : Callable + Provide product R^-1 A + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + py__obs_op_lin_pdaf : Callable + Linearized observation operator + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A and apply localizations + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_assim_offline_en3dvar_lestkf_nondiagr( + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def assim_offline_hyb3dvar_estkf_nondiagr(py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__prodrinva_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prepoststep_pdaf): + r"""assim_offline_hyb3dvar_estkf_nondiagr(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, py__prodrinva_pdaf:Callable, py__cvt_ens_pdaf:Callable, py__cvt_adj_ens_pdaf:Callable, py__cvt_pdaf:Callable, py__cvt_adj_pdaf:Callable, py__obs_op_lin_pdaf:Callable, py__obs_op_adj_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int + + Offline hybrid 3DEnVar for a single DA step + using non-diagonal observation error covariance matrix. + + See :func:`pyPDAF.PDAF3.assim_offline_3dvar_all` + for diagonal observation error covariance matrix. + + Here the background error covariance is hybridised by + a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + ESTKF in this implementation. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + 4. the iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core 3DEnVar algorithm + 5. py__cvt_pdaf + 6. py__cvt_ens_pdaf + 7. Perform ESTKF: + 1. py__init_dim_obs_pdaf + 2. py__obs_op_pdaf + (for ensemble mean) + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__prodRinvA_pdaf + 5. core ESTKF algorithm + 8. py__prepoststep_state_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + py__obs_op_pdaf : Callable + Full observation operator + py__prodrinva_pdaf : Callable + Provide product R^-1 A + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + py__obs_op_lin_pdaf : Callable + Linearized observation operator + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_assim_offline_hyb3dvar_estkf_nondiagr( + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def assim_offline_hyb3dvar_lestkf_nondiagr(py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__prodrinva_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prodrinva_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prepoststep_pdaf): + r"""assim_offline_hyb3dvar_lestkf_nondiagr(py__init_dim_obs_pdaf:Callable, py__obs_op_pdaf:Callable, py__prodrinva_pdaf:Callable, py__cvt_ens_pdaf:Callable, py__cvt_adj_ens_pdaf:Callable, py__cvt_pdaf:Callable, py__cvt_adj_pdaf:Callable, py__obs_op_lin_pdaf:Callable, py__obs_op_adj_pdaf:Callable, py__prodrinva_l_pdaf:Callable, py__init_n_domains_p_pdaf:Callable, py__init_dim_l_pdaf:Callable, py__init_dim_obs_l_pdaf:Callable, py__prepoststep_pdaf:Callable) -> int + + Offline hybrid 3DEnVar for a single DA step + using non-diagonal observation error covariance matrix. + + Here, the background error covariance is + hybridised by a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + LESTKF in this implementation. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__prepoststep_state_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + 4. The iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core DA algorithm + 5. py__cvt_pdaf + 6. py__cvt_ens_pdaf + 7. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__prodRinvA_l_pdaf + 4. core DA algorithm + 8. py__prepoststep_state_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A and apply localizations + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__next_observation_pdaf : Callable + Provide information on next forecast + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_assim_offline_hyb3dvar_lestkf_nondiagr( + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + +def assimilate_local(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, + py__l2g_state_pdaf, py__prepoststep_pdaf, py__next_observation_pdaf, + int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__g2l_state_pdaf : Callable + Get local state from full state + + py__l2g_state_pdaf : Callable + Init full state from local state + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__next_observation_pdaf : Callable + Provide information on next forecast + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaf3_assimilate_local(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assimilate_global(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf3_assimilate_global(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assimilate_lenkf(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__localize_covar_pdaf, + py__prepoststep_pdaf, py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_assimilate_lenkf` + or :func:`pyPDAF.PDAF.omi_assimilate_lenkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Stochastic EnKF (ensemble Kalman filter) + with covariance localisation [1]_ + for a single DA step without OMI. + + This is the only scheme for covariance localisation in PDAF. + + This function should be called at each model time step. + The function is a combination of + :func:`pyPDAF.PDAF.put_state_lenkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. py__localize_pdaf + 6. py__add_obs_err_pdaf + 7. py__init_obs_pdaf + 8. py__init_obscovar_pdaf + 9. py__obs_op_pdaf (repeated to reduce storage) + 10. core DA algorith + 11. py__prepoststep_state_pdaf + 12. py__distribute_state_pdaf + 13. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_assimilate_lenkf` + and :func:`pyPDAF.PDAF.omi_assimilate_lenkf_nondiagR` + + References + ---------- + .. [1] Houtekamer, P. L., and H. L. Mitchell (1998): + Data Assimilation Using an Ensemble Kalman Filter + Technique. + Mon. Wea. Rev., 126, 796–811, + doi: 10.1175/1520-0493(1998)126<0796:DAUAEK>2.0.CO;2. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__localize_covar_pdaf : Callable + Apply localization to HP and HPH^T + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.localize_covar_pdaf = py__localize_covar_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf3_assimilate_lenkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__localize_covar_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assimilate_ensrf(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__localize_covar_serial_pdaf, + py__prepoststep_pdaf, py__next_observation_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__localize_covar_serial_pdaf : Callable + Apply localization to HP and BXY for single observation + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__next_observation_pdaf : Callable + Provide information on next forecast + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.localize_covar_serial_pdaf = py__localize_covar_serial_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaf3_assimilate_ensrf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__localize_covar_serial_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + + + + +def assim_offline_local(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__prepoststep_pdaf, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__g2l_state_pdaf : Callable + Get local state from full state + + py__l2g_state_pdaf : Callable + Init full state from local state + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + with nogil: + c__pdaf3_assim_offline_local(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def assim_offline_global(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prepoststep_pdaf, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + with nogil: + c__pdaf3_assim_offline_global(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def assim_offline_lenkf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__localize_covar_pdaf, py__prepoststep_pdaf, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__localize_covar_pdaf : Callable + Apply localization to HP and HPH^T + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.localize_covar_pdaf = py__localize_covar_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + with nogil: + c__pdaf3_assim_offline_lenkf(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__localize_covar_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def assim_offline_ensrf(py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__localize_covar_serial_pdaf, py__prepoststep_pdaf, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__localize_covar_serial_pdaf : Callable + Apply localization to HP and BXY for single observation + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.localize_covar_serial_pdaf = py__localize_covar_serial_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + with nogil: + c__pdaf3_assim_offline_ensrf(pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__localize_covar_serial_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag diff --git a/pyPDAF/source/src/pyPDAF/PDAF3/meson.build b/pyPDAF/source/src/pyPDAF/PDAF3/meson.build new file mode 100644 index 0000000000000000000000000000000000000000..dd9ff845ddb198b483e2a8b38fb21cc31128c6fb --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF3/meson.build @@ -0,0 +1,25 @@ +pypdaf_sources = files('assim.pyx', + 'put.pyx', + '_pdaf3_c.pyx' + ) + +foreach file :pypdaf_sources + + cython_ext = python.extension_module( + fs.stem(file), + file, + link_with: [pdafc_lib], + dependencies : [mpi, dep_py, blas_dep, fruntime_dep], + include_directories: include_directories([incdir_numpy]), + c_args: c_cython_args, + link_args: link_args, + cython_args : cython_args, + link_language: 'fortran', + subdir: 'pyPDAF' / 'PDAF3', + install: true, + install_rpath: '$ORIGIN' + ) +endforeach + + +python.install_sources(['__init__.py', 'py.typed', '_pdaf3_c.pyi', 'assim.pyi'], subdir: 'pyPDAF/PDAF3/') diff --git a/pyPDAF/source/src/pyPDAF/PDAF3/put.pxd b/pyPDAF/source/src/pyPDAF/PDAF3/put.pxd new file mode 100644 index 0000000000000000000000000000000000000000..c5f1e31a919c65b49c3c66bae5793bac5c8534c3 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF3/put.pxd @@ -0,0 +1,375 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t +cdef extern void c__pdaf3_put_state_3dvar_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_en3dvar_estkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_en3dvar_lestkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_hyb3dvar_estkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_hyb3dvar_lestkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_3dvar_all( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_3dvar( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_en3dvar( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_en3dvar_estkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_en3dvar_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_hyb3dvar( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_hyb3dvar_estkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_hyb3dvar_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_local_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_global_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_lnetf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_lknetf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__prodrinva_hyb_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* , double* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__likelihood_hyb_l_pdaf)(int* , int* , int* , double* , + double* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_enkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_lenkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__localize_covar_pdaf)(int* , int* , double* , double* ), + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_nonlin_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__likelihood_pdaf)(int* , int* , double* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_local( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_global( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_lenkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__localize_covar_pdaf)(int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_ensrf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__localize_covar_serial_pdaf)(int* , int* , int* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaf3_put_state_generate_obs( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__get_obs_f_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/PDAF3/put.pyx b/pyPDAF/source/src/pyPDAF/PDAF3/put.pyx new file mode 100644 index 0000000000000000000000000000000000000000..de3318aba3ca3263327153c6388248a3105a3302 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAF3/put.pyx @@ -0,0 +1,2122 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + + +def put_state_3dvar_nondiagr(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__prodrinva_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prepoststep_pdaf): + r"""3DVar DA for a single DA step + using non-diagonal observation error covariance matrix + without post-processing, distributing analysis, + and setting next observation step. + + Compared to + :func:`pyPDAF.PDAF3.assimilate_3dvar_nondiagR`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. + The next DA step will not be assigned + by user-supplied functions as well. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + When 3DVar is used, the background error covariance matrix + has to be modelled for cotrol variable transformation. + This is a deterministic filtering scheme + so no ensemble and parallelisation is needed. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. Iterative optimisation: + 1. py__cvt_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_pdaf + 6. core DA algorithm + 6. py__cvt_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_3dvar_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_en3dvar_estkf_nondiagr(py__collect_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__prodrinva_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_en3dvar_estkf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_en3dvar_lestkf_nondiagr(py__collect_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__prodrinva_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A and apply localizations + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_en3dvar_lestkf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_hyb3dvar_estkf_nondiagr(py__collect_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__prodrinva_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_hyb3dvar_estkf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_hyb3dvar_lestkf_nondiagr(py__collect_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__prodrinva_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prodrinva_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A and apply localizations + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_hyb3dvar_lestkf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_3dvar_all(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__cvt_pdaf, + py__cvt_adj_pdaf, py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_3dvar_all(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_3dvar(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__prepoststep_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_put_state_3dvar` + or :func:`pyPDAF.PDAF.omi_put_state_3dvar_nondiagR`. + + PDAF-OMI modules require fewer user-supplied + functions and improved efficiency. + + 3DVar DA for a single DA step. + + Compared to :func:`pyPDAF.PDAF.assimilate_3dvar`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will not + be assigned by user-supplied functions as well. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + When 3DVar is used, the background error covariance matrix + has to be modelled for cotrol variable transformation. + This is a deterministic filtering scheme so no ensemble + and parallelisation is needed. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. Iterative optimisation: + 1. py__cvt_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_pdaf + 6. core DA algorithm + 7. py__cvt_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_put_state_3dvar` + and :func:`pyPDAF.PDAF.omi_put_state_3dvar_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_3dvar(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_en3dvar(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_en3dvar(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_en3dvar_estkf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prepoststep_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_put_state_en3dvar_estkf` + or :func:`pyPDAF.PDAF.omi_put_state_en3dvar_estkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + 3DEnVar for a single DA step. + + Compared to :func:`pyPDAF.PDAF.assimilate_en3dvar_estkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will not be + assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The background error covariance matrix is + estimated by an ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An ESTKF is used along with 3DEnVar to + generate ensemble perturbations. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core 3DEnVar algorithm + 7. py__cvt_ens_pdaf + 8. ESTKF: + 1. py__init_dim_obs_pdaf + 2. py__obs_op_pdaf (for ensemble mean) + 3. py__init_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. py__init_obsvar_pdaf + (only relevant for adaptive forgetting factor schemes) + 6. py__prodRinvA_pdaf + 7. core ESTKF algorithm + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_put_state_en3dvar_estkf` + and :func:`pyPDAF.PDAF.omi_put_state_en3dvar_estkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_en3dvar_estkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_en3dvar_lestkf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__prepoststep_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf` + or :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + 3DEnVar for a single DA step without post-processing, + distributing analysis, and setting next observation step, + where the ensemble anomaly is generated by LESTKF. + + Compared to :func:`pyPDAF.PDAF.assimilate_en3dvar_lestkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The background error covariance matrix is estimated by ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An LESTKF is used to generate ensemble perturbations. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. Starting the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core DA algorithm + 7. py__cvt_ens_pdaf + 8. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__init_obs_pdaf + (if global adaptive forgetting factor is used + `type_forget=1` in :func:`pyPDAF.PDAF.init`) + 5. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise mean ensemble in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting factor + `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf` + and :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_en3dvar_lestkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_hyb3dvar(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__cvt_pdaf, + py__cvt_adj_pdaf, py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_hyb3dvar(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_hyb3dvar_estkf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__cvt_pdaf, + py__cvt_adj_pdaf, py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, + py__prepoststep_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_estkf` + or :func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_estkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Hybrid 3DEnVar for a single DA step where + the background error covariance is hybridised by + a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + + Compared to :func:`pyPDAF.PDAF.assimilate_hyb3dvar_estkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + ESTKF in this implementation. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. the iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core 3DEnVar algorithm + 7. py__cvt_pdaf + 8. py__cvt_ens_pdaf + 9. Perform ESTKF: + 1. py__init_dim_obs_pdaf + 2. py__obs_op_pdaf + (for ensemble mean) + 3. py__init_obs_pdaf + 4. py__obs_op_pdaf + (for each ensemble member) + 5. py__init_obsvar_pdaf + (only relevant for adaptive + forgetting factor schemes) + 6. py__prodRinvA_pdaf + 7. core ESTKF algorithm + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_estkf` + and :func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_estkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_hyb3dvar_estkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_hyb3dvar_lestkf(py__collect_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__prepoststep_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf` + or :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Hybrid 3DEnVar for a single DA step using + non-diagnoal observation error covariance matrix + without post-processing, distributing analysis, + and setting next observation step, where + the background error covariance is hybridised by + a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + + Compared to :func:`pyPDAF.PDAF.assimilate_hyb3dvar_lestkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + LESTKF in this implementation. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. The iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core DA algorithm + 7. py__cvt_pdaf + 8. py__cvt_ens_pdaf + 9. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__init_obs_pdaf + (if global adaptive forgetting factor + `type_forget=1` in :func:`pyPDAF.PDAF.init`) + 5. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise mean ensemble in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting + factor `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf` + and :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_hyb3dvar_lestkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_local_nondiagr(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__prodrinva_l_pdaf, + py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prodrinva_l_pdaf : Callable + Provide product of inverse of R with matrix A + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_local_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_global_nondiagr(py__collect_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__prodrinva_pdaf, + py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prodrinva_pdaf : Callable + Provide product of inverse of R with matrix A + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_global_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_lnetf_nondiagr(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__likelihood_l_pdaf, + py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__likelihood_l_pdaf : Callable + Compute likelihood and apply localization + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_lnetf_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_lknetf_nondiagr(py__collect_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prodrinva_l_pdaf, + py__prodrinva_hyb_l_pdaf, py__likelihood_l_pdaf, py__likelihood_hyb_l_pdaf, + py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prodrinva_l_pdaf : Callable + Provide product of inverse of R with matrix A + + py__prodrinva_hyb_l_pdaf : Callable + Product R^-1 A on local analysis domain with hybrid weight + + py__likelihood_l_pdaf : Callable + Compute likelihood and apply localization + + py__likelihood_hyb_l_pdaf : Callable + Compute likelihood and apply localization with tempering + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.prodrinva_hyb_l_pdaf = py__prodrinva_hyb_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.likelihood_hyb_l_pdaf = py__likelihood_hyb_l_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_lknetf_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__prodrinva_hyb_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__likelihood_hyb_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_enkf_nondiagr(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__add_obs_err_pdaf, py__init_obs_covar_pdaf, + py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__add_obs_err_pdaf : Callable + Add observation error covariance matrix + + py__init_obs_covar_pdaf : Callable + Initialize mean observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_enkf_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_lenkf_nondiagr(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__localize_covar_pdaf, + py__add_obs_err_pdaf, py__init_obs_covar_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + py__localize_covar_pdaf : Callable + Apply covariance localization + + py__add_obs_err_pdaf : Callable + Add observation error covariance matrix + + py__init_obs_covar_pdaf : Callable + Initialize mean observation error variance + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.localize_covar_pdaf = py__localize_covar_pdaf + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_lenkf_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__localize_covar_pdaf, + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_nonlin_nondiagr(py__collect_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__likelihood_pdaf, + py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__likelihood_pdaf : Callable + Compute likelihood + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.likelihood_pdaf = py__likelihood_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_nonlin_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__likelihood_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prepoststep_pdaf, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + with nogil: + c__pdaf3_put_state(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_local(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__prepoststep_pdaf, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + py__g2l_state_pdaf : Callable + Get local state from full state + + py__l2g_state_pdaf : Callable + Init full state from local state + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + with nogil: + c__pdaf3_put_state_local(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_global(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__prepoststep_pdaf, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + with nogil: + c__pdaf3_put_state_global(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_lenkf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__localize_covar_pdaf, py__prepoststep_pdaf, + int outflag): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_put_state_lenkf` + or :func:`pyPDAF.PDAF.omi_put_state_lenkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Stochastic EnKF (ensemble Kalman filter) + with covariance localisation [1]_ + for a single DA step without OMI. + + Compared to :func:`pyPDAF.PDAF.assimilate_lenkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + This is the only scheme for covariance localisation in PDAF. + + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. py__localize_pdaf + 6. py__add_obs_err_pdaf + 7. py__init_obs_pdaf + 8. py__init_obscovar_pdaf + 9. py__obs_op_pdaf (repeated to reduce storage) + 10. core DA algorith + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_put_state_lenkf` + and :func:`pyPDAF.PDAF.omi_put_state_lenkf_nondiagR` + + References + ---------- + .. [1] Houtekamer, P. L., and H. L. Mitchell (1998): + Data Assimilation Using an Ensemble Kalman + Filter Technique. + Mon. Wea. Rev., 126, 796–811, + doi: 10.1175/1520-0493(1998)126<0796:DAUAEK>2.0.CO;2. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__localize_covar_pdaf : Callable + Apply localization to HP and HPH^T + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.localize_covar_pdaf = py__localize_covar_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + with nogil: + c__pdaf3_put_state_lenkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__localize_covar_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_ensrf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__localize_covar_serial_pdaf, py__prepoststep_pdaf, + int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__localize_covar_serial_pdaf : Callable + Apply localization to HP and BXY for single observation + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.localize_covar_serial_pdaf = py__localize_covar_serial_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + with nogil: + c__pdaf3_put_state_ensrf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__localize_covar_serial_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_generate_obs(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__get_obs_f_pdaf, py__prepoststep_pdaf): + """Generation of synthetic observations + based on given error statistics and observation operator + without post-processing, distributing analysis, + and setting next observation step. + + When diagonal observation error covariance matrix is used, + it is recommended to use + :func:`pyPDAF.PDAF.omi_generate_obs` functionalities + for fewer user-supplied functions and improved efficiency. + + The generated synthetic observations are + based on each member of model forecast. + Therefore, an ensemble of observations can be obtained. + In a typical experiment, + one may only need one ensemble member. + + Compared to :func:`pyPDAF.PDAF.generate_obs`, + this function has no :func:`get_state` call. + This means that the next DA step will + not be assigned by user-supplied functions. + This function is typically used when there + are not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The implementation strategy is similar to + an assimilation step. This means that, + one can reuse many user-supplied functions for + assimilation and observation generation. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pda + 5. py__init_obserr_f_pdaf + 6. py__get_obs_f_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + py__get_obs_f_pdaf : Callable + Initialize observation vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.get_obs_f_pdaf = py__get_obs_f_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaf3_put_state_generate_obs(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__get_obs_f_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + diff --git a/pyPDAF/source/src/pyPDAF/PDAF3/py.typed b/pyPDAF/source/src/pyPDAF/PDAF3/py.typed new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/pyPDAF/source/src/pyPDAF/PDAFlocal/__init__.py b/pyPDAF/source/src/pyPDAF/PDAFlocal/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0afd97008538cec2139bbf175e52fa8fea7499da --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFlocal/__init__.py @@ -0,0 +1,3 @@ +"""Module file for PDAFlocal +""" +from ._pdaflocal_c import set_indices, set_increment_weights, clear_increment_weights diff --git a/pyPDAF/source/src/pyPDAF/PDAFlocal/_pdaflocal_c.pxd b/pyPDAF/source/src/pyPDAF/PDAFlocal/_pdaflocal_c.pxd new file mode 100644 index 0000000000000000000000000000000000000000..3a3a11c4f6f9386224ae0b4c9d30880a28d91dc8 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFlocal/_pdaflocal_c.pxd @@ -0,0 +1,9 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t +cdef extern void c__pdaflocal_set_indices(int* dim_l, + int* map) noexcept nogil; + +cdef extern void c__pdaflocal_set_increment_weights(int* dim_l, + double* weights) noexcept nogil; + +cdef extern void c__pdaflocal_clear_increment_weights() noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/PDAFlocal/_pdaflocal_c.pyi b/pyPDAF/source/src/pyPDAF/PDAFlocal/_pdaflocal_c.pyi new file mode 100644 index 0000000000000000000000000000000000000000..52fbb49f0ce2795c30536c6405f733dfa9952729 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFlocal/_pdaflocal_c.pyi @@ -0,0 +1,54 @@ +# pylint: disable=unused-argument +"""Stub file for PDAFlocal module +""" +import numpy as np + +def set_indices(dim_l: int, map: np.ndarray) -> None: + r"""Set index vector to map local state vector to global state vectors. + + This is called in the user-supplied function `py__init_dim_l_pdaf`. + This function only sets the mapping for given domain index `domain_p` + between local state vector and global state vector. + Each element of map is an index of the global state vector. The index starts from 1. + + E.g., map[0] = 2 means that the first element of local state vector is the + 2rd element of the global state vector. + + Parameters + ---------- + dim_l : int + Dimension of local state vector + map : ndarray[np.intc, dim=1] + Index array for mapping between local and global state vector + shape: (dim_l,) + """ + +def set_increment_weights(dim_l: int, weights: np.ndarray) -> None: + r"""Initialises a PDAF_internal local array of increment weights. + + This is called in the user-supplied function `py__init_dim_l_pdaf`. + + The weights are applied in in :func:`pyPDAF.PDAFlocal.l2g_cb` where the local state vector + is weighted by given weights. These can e.g. be used to apply a vertical localisation. + + In vertical localization, the local state vector is a full vertical column + of the model grid. In this case, one can make the increment weight depending + on the height (or depth) of a grid point. + + Another application is to implement weakly-coupled assimilation in which + the local state vector contains all variables, but only a subset of them is updated. + + This is achieved by givening those element that should not be updated the weight 0. + + Parameters + ---------- + dim_l : int + Dimension of local state vector + weights : ndarray[np.float64, dim=1] + Weights array. Shape: (dim_l,) + """ + +def clear_increment_weights() -> None: + r"""Deallocates the local increment weight vector in + :func:`pyPDAF.PDAFlocal.set_increment_weights`. + """ diff --git a/pyPDAF/source/src/pyPDAF/PDAFlocal/_pdaflocal_c.pyx b/pyPDAF/source/src/pyPDAF/PDAFlocal/_pdaflocal_c.pyx new file mode 100644 index 0000000000000000000000000000000000000000..cf6e34edda8f6780661dd04291aaa63725e648a3 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFlocal/_pdaflocal_c.pyx @@ -0,0 +1,75 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + +def set_indices(int dim_l, int [::1] map): + r"""set_indices(dim_l: int, map: np.ndarray) -> None + + Set index vector to map local state vector to global state vectors. + + This is called in the user-supplied function `py__init_dim_l_pdaf`. + This function only sets the mapping for given domain index `domain_p` + between local state vector and global state vector. + Each element of map is an index of the global state vector. The index starts from 1. + + E.g., map[0] = 2 means that the first element of local state vector is the + 2rd element of the global state vector. + + Parameters + ---------- + dim_l : int + Dimension of local state vector + map : ndarray[np.intc, dim=1] + Index array for mapping between local and global state vector + shape: (dim_l,) + """ + with nogil: + c__pdaflocal_set_indices(&dim_l, &map[0]) + + + +def set_increment_weights(int dim_l, double [::1] weights): + r"""set_increment_weights(dim_l: int, weights: np.ndarray) -> None + + Initialises a PDAF_internal local array of increment weights. + + This is called in the user-supplied function `py__init_dim_l_pdaf`. + + The weights are applied in in :func:`pyPDAF.PDAFlocal.l2g_cb` where the local state vector + is weighted by given weights. These can e.g. be used to apply a vertical localisation. + + In vertical localization, the local state vector is a full vertical column + of the model grid. In this case, one can make the increment weight depending + on the height (or depth) of a grid point. + + Another application is to implement weakly-coupled assimilation in which + the local state vector contains all variables, but only a subset of them is updated. + + This is achieved by givening those element that should not be updated the weight 0. + + Parameters + ---------- + dim_l : int + Dimension of local state vector + weights : ndarray[np.float64, dim=1] + Weights array. Shape: (dim_l,) + """ + with nogil: + c__pdaflocal_set_increment_weights(&dim_l, &weights[0]) + + + +def clear_increment_weights(): + r"""clear_increment_weights() -> None + + Deallocates the local increment weight vector in :func:`pyPDAF.PDAFlocal.set_increment_weights`. + """ + with nogil: + c__pdaflocal_clear_increment_weights() + + + diff --git a/pyPDAF/source/src/pyPDAF/PDAFlocal/assim.pxd b/pyPDAF/source/src/pyPDAF/PDAFlocal/assim.pxd new file mode 100644 index 0000000000000000000000000000000000000000..41516596c2def67e1bfee439419718b13bd75158 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFlocal/assim.pxd @@ -0,0 +1,175 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t +cdef extern void c__pdaflocal_assimilate_en3dvar_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_f_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocal_assimilate_hyb3dvar_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_f_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocal_assimilate_lseik( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocal_assimilate_letkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocal_assimilate_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocal_assimilate_lnetf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocal_assimilate_lknetf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__prodrinva_hyb_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__likelihood_hyb_l_pdaf)(int* , int* , int* , double* , + double* , double* , double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/PDAFlocal/assim.pyx b/pyPDAF/source/src/pyPDAF/PDAFlocal/assim.pyx new file mode 100644 index 0000000000000000000000000000000000000000..b3c5c4ea20879171c05acb688711a98f25f93454 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFlocal/assim.pyx @@ -0,0 +1,3613 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + +try: + import mpi4py + mpi4py.rc.initialize = False +except ImportError: + pass + +# Global error handler +def global_except_hook(exctype, value, traceback): + from traceback import print_exception + try: + import mpi4py.MPI + + if mpi4py.MPI.Is_initialized(): + try: + sys.stderr.write('Uncaught exception was ''detected on rank {}.\n'.format( + mpi4py.MPI.COMM_WORLD.Get_rank())) + print_exception(exctype, value, traceback) + sys.stderr.write("\n") + sys.stderr.flush() + finally: + try: + mpi4py.MPI.COMM_WORLD.Abort(1) + except Exception as e: + sys.stderr.write('MPI Abort failed, this process will hang.\n') + sys.stderr.flush() + raise e + else: + sys.__excepthook__(exctype, value, traceback) + except ImportError: + sys.__excepthook__(exctype, value, traceback) + +sys.excepthook = global_except_hook + +def assimilate_en3dvar_lestkf(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__prodrinva_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, + py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, py__init_obs_f_pdaf, + py__init_obs_l_pdaf, py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_obs_pdaf, + py__init_obsvar_pdaf, py__init_obsvar_l_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf` or + :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + 3DEnVar for a single DA step where the ensemble anomaly + is generated by LESTKF. + The background error covariance matrix is + estimated by ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An LESTKF is used to generate ensemble perturbations. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_en3dvar_lestkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. Starting the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core DA algorithm + 7. py__cvt_ens_pdaf + 8. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__init_obs_pdaf + (if global adaptive forgetting factor is used + `type_forget=1` in :func:`pyPDAF.PDAF.init`) + 5. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise mean ensemble in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local + adaptive forgetting factor + `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + 9. py__prepoststep_state_pdaf + 10. py__distribute_state_pdaf + 11. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf` + and + :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble var) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_f_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Size of the full observation vector + + Callback Returns + ---------------- + observation_f : ndarray[np.float64, ndim=1] + Full vector of observations + Array shape: (dim_obs_f) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.init_obs_f_pdaf = py__init_obs_f_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaflocal_assimilate_en3dvar_lestkf( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__init_obs_f_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_hyb3dvar_lestkf(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__init_obs_pdaf, py__prodrinva_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__init_dim_obs_f_pdaf, + py__obs_op_f_pdaf, py__init_obs_f_pdaf, py__init_obs_l_pdaf, + py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_obs_pdaf, py__init_obsvar_pdaf, + py__init_obsvar_l_pdaf, py__prepoststep_pdaf, py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf` or + :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Hybrid 3DEnVar for a single DA step where + the background error covariance is hybridised by + a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + LESTKF in this implementation. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_hyb3dvar_lestkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. The iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core DA algorithm + 7. py__cvt_pdaf + 8. py__cvt_ens_pdaf + 9. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__init_obs_pdaf + (if global adaptive forgetting factor + `type_forget=1` in :func:`pyPDAF.PDAF.init`) + 5. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise mean ensemble in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting + factor `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + 10. py__prepoststep_state_pdaf + 11. py__distribute_state_pdaf + 12. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf` + and + :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble var) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_f_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Size of the full observation vector + + Callback Returns + ---------------- + observation_f : ndarray[np.float64, ndim=1] + Full vector of observations + Array shape: (dim_obs_f) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.init_obs_f_pdaf = py__init_obs_f_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaflocal_assimilate_hyb3dvar_lestkf( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__init_obs_f_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_lseik(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__init_obs_l_pdaf, py__prepoststep_pdaf, py__prodrinva_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_obs_pdaf, py__init_obsvar_pdaf, + py__init_obsvar_l_pdaf, py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_assimilate` + or :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`. + + PDAF-OMI modules require fewer user-supplied + functions and improved efficiency. + + Local singular evolutive interpolated Kalman filter [1]_ + for a single DA step. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_lseik` and :func:`pyPDAF.PDAF.get_state` + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. py__init_obs_pdaf + (if global adaptive forgetting factor `type_forget=1` + is used in :func:`pyPDAF.PDAF.init`) + 7. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 8. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf (localise mean ensemble + in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting + factor `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + 9. py__prepoststep_state_pdaf + 10. py__distribute_state_pdaf + 11. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_assimilate` + and :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR` + + References + ---------- + .. [1] Pham, D. T., Verron, J., & Roubaud, M. C. (1998). + A singular evolutive extended Kalman filter + for data assimilation + in oceanography. Journal of Marine systems, + 16(3-4), 323-340. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaflocal_assimilate_lseik(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_letkf(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__init_obs_l_pdaf, py__prepoststep_pdaf, py__prodrinva_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_obs_pdaf, py__init_obsvar_pdaf, + py__init_obsvar_l_pdaf, py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_assimilate` + or :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`. + + PDAFlocal-OMI modules require fewer user-supplied + functions and improved efficiency. + + Local ensemble transform Kalman filter (LETKF) [1]_ for a single DA step without OMI. + Implementation is based on [2]_. + Note that the LESTKF is a more efficient equivalent + to the LETKF. + + This function should be called at each model time step. + The function is a combination of + :func:`pyPDAF.PDAF.put_state_letkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. py__init_obs_pdaf + (if global adaptive forgetting factor + `type_forget=1` is used + in :func:`pyPDAF.PDAF.init`) + 7. py__init_obsvar_pdaf (if global adaptive + forgetting factor is used) + 8. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf (localise mean ensemble + in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting factor + `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + 9. py__prepoststep_state_pdaf + 10. py__distribute_state_pdaf + 11. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_assimilate` + and :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR` + + References + ---------- + .. [1] Hunt, B. R., Kostelich, E. J., & Szunyogh, I. (2007). + Efficient data assimilation for spatiotemporal chaos: + A local ensemble transform Kalman filter. + Physica D: Nonlinear Phenomena, 230(1-2), 112-126. + .. [2] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaflocal_assimilate_letkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_lestkf(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__init_obs_l_pdaf, py__prepoststep_pdaf, py__prodrinva_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_obs_pdaf, py__init_obsvar_pdaf, + py__init_obsvar_l_pdaf, py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_assimilate` + or :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`. + + PDAFlocal-OMI modules require fewer user-supplied + functions and improved efficiency. + + Local ESTKF (error space transform Kalman filter) [1]_ for a single DA step without OMI. + The LESTKF is a more efficient equivalent to the LETKF. + + This function should be called at each model time step. + The function is a combination of + :func:`pyPDAF.PDAF.put_state_lestkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. py__init_obs_pdaf + (if global adaptive forgetting factor + `type_forget=1` is used + in :func:`pyPDAF.PDAF.init`) + 7. py__init_obsvar_pdaf (if global adaptive + forgetting factor is used) + 8. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf (localise mean ensemble + in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive + forgetting factor `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + 9. py__prepoststep_state_pdaf + 10. py__distribute_state_pdaf + 11. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_assimilate` + and :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR` + + References + ---------- + .. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaflocal_assimilate_lestkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_lnetf(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__init_obs_l_pdaf, py__prepoststep_pdaf, py__likelihood_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_obs_pdaf, py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_assimilate` + or :func:`pyPDAF.PDAF.localomi_assimilate_lnetf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Local Nonlinear Ensemble Transform Filter (LNETF) [1]_ + for a single DA step. + The nonlinear filter computes the distribution up to + the second moment similar to Kalman filters but + it uses a nonlinear weighting similar to + particle filters. This leads to an equal weights assumption + for the prior ensemble at each step. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_lnetf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__init_obs_l_pdaf + 5. py__g2l_obs_pdaf (localise each ensemble + member in observation space) + 6. py__likelihood_l_pdaf + 7. core DA algorithm + 8. py__l2g_state_pdaf + 7. py__prepoststep_state_pdaf + 8. py__distribute_state_pdaf + 9. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_assimilate` + and :func:`pyPDAF.PDAF.localomi_assimilate_lnetf_nondiagR` + + References + ---------- + .. [1] Tödter, J., and B. Ahrens, 2015: + A second-order exact ensemble square root filter + for nonlinear data assimilation. Mon. Wea. Rev., + 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__likelihood_l_pdaf : Callable + Compute observation likelihood for an ensemble member + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaflocal_assimilate_lnetf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_lknetf(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__init_obs_l_pdaf, py__prepoststep_pdaf, py__prodrinva_l_pdaf, + py__prodrinva_hyb_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_obs_pdaf, + py__init_obsvar_pdaf, py__init_obsvar_l_pdaf, py__likelihood_l_pdaf, + py__likelihood_hyb_l_pdaf, py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_assimilate` + or :func:`pyPDAF.PDAF.localomi_assimilate_lknetf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + A hybridised LETKF and LNETF [1]_ for a single DA step. + The LNETF computes the distribution up to + the second moment similar to Kalman filters but + using a nonlinear weighting similar to + particle filters. This leads to an equal weights + assumption for the prior ensemble. + The hybridisation with LETKF is expected to lead to + improved performance for quasi-Gaussian problems. + The function should be called at each model step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_lknetf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf + (for each ensemble member) + 6. py__init_obs_pdaf + (if global adaptive forgetting factor `type_forget=1` + is used in :func:`pyPDAF.PDAF.init`) + 7. py__init_obsvar_pdaf (if global adaptive + forgetting factor is used) + 8. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise each ensemble member + in observation space) + 5. py__init_obs_l_pdaf + 6. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting + factor `type_forget=2` is used) + 7. py__prodRinvA_pdaf + 8. py__likelihood_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + 9. py__obs_op_pdaf + (only called with `HKN` and `HNK` options + called for each ensemble member) + 10. py__likelihood_hyb_l_pda + 11. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting + factor `type_forget=2` is used) + 12. py__prodRinvA_hyb_l_pdaf + 13. py__prepoststep_state_pdaf + 14. py__distribute_state_pdaf + 15. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_assimilate` + and :func:`pyPDAF.PDAF.localomi_assimilate_lknetf_nondiagR` + + References + ---------- + .. [1] Nerger, L.. (2022) + Data assimilation for nonlinear systems with + a hybrid nonlinear Kalman ensemble transform filter. + Q J R Meteorol Soc, 620–640. doi:10.1002/qj.4221 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__prodrinva_hyb_l_pdaf : Callable + Provide product R^-1 A on local analysis domain with hybrid weight + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + dim_ens : int + Number of the columns in the matrix processes here. This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__likelihood_l_pdaf : Callable + Compute likelihood + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__likelihood_hyb_l_pdaf : Callable + Compute likelihood with hybrid weight + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__next_observation_pdaf : Callable + Routine to provide time step, time and dimensionof next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.prodrinva_hyb_l_pdaf = py__prodrinva_hyb_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.likelihood_hyb_l_pdaf = py__likelihood_hyb_l_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdaflocal_assimilate_lknetf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__prodrinva_hyb_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__likelihood_hyb_l_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + diff --git a/pyPDAF/source/src/pyPDAF/PDAFlocal/internal.pxd b/pyPDAF/source/src/pyPDAF/PDAFlocal/internal.pxd new file mode 100644 index 0000000000000000000000000000000000000000..4e4dfa376aaead78773492b8385315b8725f9001 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFlocal/internal.pxd @@ -0,0 +1,8 @@ + +cdef extern void c__pdaflocal_g2l_cb(int* step, int* domain_p, int* dim_p, + double* state_p, int* dim_l, + double* state_l) noexcept nogil; + +cdef extern void c__pdaflocal_l2g_cb(int* step, int* domain_p, int* dim_l, + double* state_l, int* dim_p, + double* state_p) noexcept nogil; \ No newline at end of file diff --git a/pyPDAF/source/src/pyPDAF/PDAFlocal/internal.pyx b/pyPDAF/source/src/pyPDAF/PDAFlocal/internal.pyx new file mode 100644 index 0000000000000000000000000000000000000000..9ddba8a3b717d30bc36e37815f6ae47fab2bbc90 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFlocal/internal.pyx @@ -0,0 +1,82 @@ +import numpy as np +cimport numpy as cnp + +def g2l_cb(int step, int domain_p, int dim_p, double [::1] state_p, + int dim_l): + r"""Project a global to a local state vector for the localized filters. + + This is the full callback function to be used internally. + The mapping is done using the index vector id_lstate_in_pstate that is + initialised in `pyPDAF.PDAFlocal.set_indices`. + + Parameters + ---------- + step : int + Current time step + domain_p : int + Current local analysis domain + dim_p : int + PE-local full state dimension + state_p : ndarray[tuple[dim_p, ...], np.float64] + PE-local full state vector + The array dimension `dim_p` is PE-local full state dimension + dim_l : int + Local state dimension + + Returns + ------- + state_l : ndarray[tuple[dim_l, ...], np.float64] + State vector on local analysis domain + + The array dimension `dim_l` is Local state dimension + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_l_np = np.zeros((dim_l), dtype=np.float64, order="F") + cdef double [::1] state_l = state_l_np + with nogil: + c__pdaflocal_g2l_cb(&step, &domain_p, &dim_p, &state_p[0], &dim_l, + &state_l[0]) + + return state_l_np + + +def l2g_cb(int step, int domain_p, int dim_l, double [::1] state_l, + int dim_p, double [::1] state_p): + r"""Initialise elements of a global state vector from a local state vector. + + This is the full callback function to be used internally. + The mapping is done using the index vector `id_lstate_in_pstate` that is + initialised in :func:`pyPDAF.PDAFlocal.set_indices`. + + To exclude any element of the local state vector from the initialisationone + can set the corresponding index value to 0. + + Parameters + ---------- + step : int + Current time step + domain_p : int + Current local analysis domain + dim_l : int + Local state dimension + state_l : ndarray[tuple[dim_l, ...], np.float64] + State vector on local analysis domain + The array dimension `dim_l` is Local state dimension + dim_p : int + PE-local full state dimension + state_p : ndarray[tuple[dim_p, ...], np.float64] + PE-local full state vector + The array dimension `dim_p` is PE-local full state dimension + + Returns + ------- + state_p : ndarray[tuple[dim_p, ...], np.float64] + PE-local full state vector + + The array dimension `dim_p` is PE-local full state dimension + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + with nogil: + c__pdaflocal_l2g_cb(&step, &domain_p, &dim_l, &state_l[0], &dim_p, + &state_p[0]) + + return state_p_np \ No newline at end of file diff --git a/pyPDAF/source/src/pyPDAF/PDAFlocal/meson.build b/pyPDAF/source/src/pyPDAF/PDAFlocal/meson.build new file mode 100644 index 0000000000000000000000000000000000000000..5b65dafd143968995a7f4f88f717242d9e3992a8 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFlocal/meson.build @@ -0,0 +1,25 @@ +pypdaf_sources = files('assim.pyx', + '_pdaflocal_c.pyx', + 'put.pyx', + 'internal.pyx' + ) + +foreach file :pypdaf_sources + + cython_ext = python.extension_module( + fs.stem(file), + file, + link_with: [pdafc_lib], + dependencies : [mpi, dep_py, blas_dep, fruntime_dep], + include_directories: include_directories([incdir_numpy ]), + c_args: c_cython_args, + link_args: link_args, + cython_args : cython_args, + link_language: 'fortran', + subdir: 'pyPDAF' / 'PDAFlocal', + install: true, + install_rpath: '$ORIGIN' + ) +endforeach + +python.install_sources(['__init__.py', 'py.typed', '_pdaflocal_c.pyi'], subdir: 'pyPDAF/PDAFlocal/') \ No newline at end of file diff --git a/pyPDAF/source/src/pyPDAF/PDAFlocal/put.pxd b/pyPDAF/source/src/pyPDAF/PDAFlocal/put.pxd new file mode 100644 index 0000000000000000000000000000000000000000..cfb988baabfbe37715fc6e3b32fe7b502d1d5ddf --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFlocal/put.pxd @@ -0,0 +1,161 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t +cdef extern void c__pdaflocal_put_state_en3dvar_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_f_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocal_put_state_hyb3dvar_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_f_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocal_put_state_lseik( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocal_put_state_letkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocal_put_state_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocal_put_state_lnetf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocal_put_state_lknetf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_obs_pdaf)(int* , int* , double* ), + void (*c__init_obs_l_pdaf)(int* , int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__prodrinva_hyb_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_obs_pdaf)(int* , int* , int* , int* , int* , int* ), + void (*c__init_obsvar_pdaf)(int* , int* , double* , double* ), + void (*c__init_obsvar_l_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__likelihood_hyb_l_pdaf)(int* , int* , int* , double* , + double* , double* , double* ), + int* outflag) noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/PDAFlocal/put.pyx b/pyPDAF/source/src/pyPDAF/PDAFlocal/put.pyx new file mode 100644 index 0000000000000000000000000000000000000000..1d1257eb0e4c4c91b50fdce7e2c83fd259813106 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFlocal/put.pyx @@ -0,0 +1,3355 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + +try: + import mpi4py + mpi4py.rc.initialize = False +except ImportError: + pass + +# Global error handler +def global_except_hook(exctype, value, traceback): + from traceback import print_exception + try: + import mpi4py.MPI + + if mpi4py.MPI.Is_initialized(): + try: + sys.stderr.write('Uncaught exception was ''detected on rank {}.\n'.format( + mpi4py.MPI.COMM_WORLD.Get_rank())) + print_exception(exctype, value, traceback) + sys.stderr.write("\n") + sys.stderr.flush() + finally: + try: + mpi4py.MPI.COMM_WORLD.Abort(1) + except Exception as e: + sys.stderr.write('MPI Abort failed, this process will hang.\n') + sys.stderr.flush() + raise e + else: + sys.__excepthook__(exctype, value, traceback) + except ImportError: + sys.__excepthook__(exctype, value, traceback) + +sys.excepthook = global_except_hook + +def put_state_en3dvar_lestkf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__prodrinva_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, + py__init_obs_f_pdaf, py__init_obs_l_pdaf, py__prodrinva_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_obs_pdaf, py__init_obsvar_pdaf, + py__init_obsvar_l_pdaf, py__prepoststep_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf` + or :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + 3DEnVar for a single DA step without post-processing, + distributing analysis, and setting next observation step, + where the ensemble anomaly is generated by LESTKF. + + Compared to :func:`pyPDAF.PDAF.assimilate_en3dvar_lestkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The background error covariance matrix is estimated by ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An LESTKF is used to generate ensemble perturbations. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. Starting the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core DA algorithm + 7. py__cvt_ens_pdaf + 8. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__init_obs_pdaf + (if global adaptive forgetting factor is used + `type_forget=1` in :func:`pyPDAF.PDAF.init`) + 5. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise mean ensemble in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting factor + `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf` + and :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble var) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_f_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Size of the full observation vector + + Callback Returns + ---------------- + observation_f : ndarray[np.float64, ndim=1] + Full vector of observations + Array shape: (dim_obs_f) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.init_obs_f_pdaf = py__init_obs_f_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaflocal_put_state_en3dvar_lestkf( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__init_obs_f_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_hyb3dvar_lestkf(py__collect_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__init_obs_pdaf, + py__prodrinva_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__cvt_pdaf, py__cvt_adj_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, + py__init_obs_f_pdaf, py__init_obs_l_pdaf, py__prodrinva_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_obs_pdaf, py__init_obsvar_pdaf, + py__init_obsvar_l_pdaf, py__prepoststep_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf` + or :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Hybrid 3DEnVar for a single DA step using + non-diagnoal observation error covariance matrix + without post-processing, distributing analysis, + and setting next observation step, where + the background error covariance is hybridised by + a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + + Compared to :func:`pyPDAF.PDAF.assimilate_hyb3dvar_lestkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + LESTKF in this implementation. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. The iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core DA algorithm + 7. py__cvt_pdaf + 8. py__cvt_ens_pdaf + 9. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__init_obs_pdaf + (if global adaptive forgetting factor + `type_forget=1` in :func:`pyPDAF.PDAF.init`) + 5. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise mean ensemble in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting + factor `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf` + and :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix (ensemble) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix (ensemble var) + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_f_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Size of the full observation vector + + Callback Returns + ---------------- + observation_f : ndarray[np.float64, ndim=1] + Full vector of observations + Array shape: (dim_obs_f) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.init_obs_f_pdaf = py__init_obs_f_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaflocal_put_state_hyb3dvar_lestkf( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__init_obs_f_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_lseik(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__init_obs_l_pdaf, + py__prepoststep_pdaf, py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_obs_pdaf, + py__init_obsvar_pdaf, py__init_obsvar_l_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_put_state` + or :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Local singular evolutive interpolated Kalman filter [1]_ + for a single DA step. + + Compared to :func:`pyPDAF.PDAF.assimilate_lseik`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. py__init_obs_pdaf + (if global adaptive forgetting factor `type_forget=1` + is used in :func:`pyPDAF.PDAF.init`) + 7. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 8. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf (localise mean ensemble + in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting factor + `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_put_state` + and :func:`pyPDAF.PDAF.localomi_put_state_nondiagR` + + References + ---------- + .. [1] Pham, D. T., Verron, J., & Roubaud, M. C. (1998). + A singular evolutive extended Kalman filter for data assimilation + in oceanography. Journal of Marine systems, 16(3-4), 323-340. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + cdef int outflag + with nogil: + c__pdaflocal_put_state_lseik(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, &outflag) + + return outflag + + +def put_state_letkf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__init_obs_l_pdaf, + py__prepoststep_pdaf, py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_obs_pdaf, + py__init_obsvar_pdaf, py__init_obsvar_l_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_put_state` + or :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`. + + PDAFlocal-OMI modules require fewer user-supplied + functions and improved efficiency. + + Local ensemble transform Kalman filter (LETKF) [1]_ + for a single DA step without OMI. + Implementation is based on [2]_. + + Compared to :func:`pyPDAF.PDAF.assimilate_letkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + Note that the LESTKF is a more efficient equivalent to the LETKF. + + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. py__init_obs_pdaf + (if global adaptive forgetting factor + `type_forget=1` is used + in :func:`pyPDAF.PDAF.init`) + 7. py__init_obsvar_pdaf (if global adaptive forgetting + factor is used) + 8. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf (localise mean ensemble + in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting factor + `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_put_state` + and :func:`pyPDAF.PDAF.localomi_put_state_nondiagR` + + References + ---------- + .. [1] Hunt, B. R., Kostelich, E. J., & Szunyogh, I. (2007). + Efficient data assimilation for spatiotemporal chaos: + A local ensemble transform Kalman filter. + Physica D: Nonlinear Phenomena, 230(1-2), 112-126. + .. [2] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + cdef int outflag + with nogil: + c__pdaflocal_put_state_letkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, &outflag) + + return outflag + + +def put_state_lestkf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__init_obs_l_pdaf, + py__prepoststep_pdaf, py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_obs_pdaf, + py__init_obsvar_pdaf, py__init_obsvar_l_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_put_state` + or :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`. + + PDAFlocal-OMI modules require fewer user-supplied functions + and improved efficiency. + + Local ESTKF (error space transform Kalman filter) [1]_ for a single DA step without OMI. + + Compared to :func:`pyPDAF.PDAF.assimilate_lestkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The LESTKF is a more efficient equivalent to the LETKF. + + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. py__init_obs_pdaf + (if global adaptive forgetting factor `type_forget=1` is used + in :func:`pyPDAF.PDAF.init`) + 7. py__init_obsvar_pdaf (if global adaptive + forgetting factor is used) + 8. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf (localise mean ensemble + in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting factor + `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_put_state` + and :func:`pyPDAF.PDAF.localomi_put_state_nondiagR` + + References + ---------- + .. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). + A unification of ensemble square root Kalman filters. + Monthly Weather Review, 140, 2335-2345. + doi:10.1175/MWR-D-11-00102.1 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + cdef int outflag + with nogil: + c__pdaflocal_put_state_lestkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, &outflag) + + return outflag + + +def put_state_lnetf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__init_obs_l_pdaf, + py__prepoststep_pdaf, py__likelihood_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_obs_pdaf): + """It is recommended to use :func:`pyPDAF.PDAF.localomi_put_state` + or :func:`pyPDAF.PDAF.localomi_put_state_lnetf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Local Nonlinear Ensemble Transform Filter (LNETF) [1]_ + for a single DA step. + + Compared to :func:`pyPDAF.PDAF.assimilate_lnetf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The nonlinear filter computes the distribution up to + the second moment similar to Kalman filters + but it uses a nonlinear weighting similar to + particle filters. This leads to an equal weights + assumption for the prior ensemble at each step. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf (for each ensemble member) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__init_obs_l_pdaf + 5. py__g2l_obs_pdaf (localise each ensemble member + in observation space) + 6. py__likelihood_l_pdaf + 7. core DA algorithm + 8. py__l2g_state_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_put_state` + and :func:`pyPDAF.PDAF.localomi_put_state_lnetf_nondiagR` + + References + ---------- + .. [1] Tödter, J., and B. Ahrens, 2015: + A second-order exact ensemble square root filter + for nonlinear data assimilation. Mon. Wea. Rev., + 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__likelihood_l_pdaf : Callable + Compute observation likelihood for an ensemble member + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + cdef int outflag + with nogil: + c__pdaflocal_put_state_lnetf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_obs_pdaf, &outflag) + + return outflag + + +def put_state_lknetf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__init_obs_pdaf, py__init_obs_l_pdaf, + py__prepoststep_pdaf, py__prodrinva_l_pdaf, py__prodrinva_hyb_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_obs_pdaf, py__init_obsvar_pdaf, + py__init_obsvar_l_pdaf, py__likelihood_l_pdaf, py__likelihood_hyb_l_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_put_state` + or :func:`pyPDAF.PDAF.localomi_put_state_lknetf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + A hybridised LETKF and LNETF [1]_ for a single DA step. + + Compared to :func:`pyPDAF.PDAF.assimilate_lknetf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The LNETF computes the distribution up to + the second moment similar to Kalman filters but + using a nonlinear weighting similar to + particle filters. This leads to an equal weights + assumption for the prior ensemble. + The hybridisation with LETKF is expected to lead to + improved performance for + quasi-Gaussian problems. + The function should be called at each model step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_n_domains_p_pdaf + 4. py__init_dim_obs_pdaf + 5. py__obs_op_pdaf + (for each ensemble member) + 6. py__init_obs_pdaf + (if global adaptive forgetting factor `type_forget=1` + is used in :func:`pyPDAF.PDAF.init`) + 7. py__init_obsvar_pdaf (if global adaptive + forgetting factor is used) + 8. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise each ensemble member in observation space) + 5. py__init_obs_l_pdaf + 6. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting factor + `type_forget=2` is used) + 7. py__prodRinvA_pdaf + 8. py__likelihood_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + 9. py__obs_op_pdaf + (only called with `HKN` and `HNK` options called + for each ensemble member) + 10. py__likelihood_hyb_l_pda + 11. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting factor + `type_forget=2` is used) + 12. py__prodRinvA_hyb_l_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_put_state` + and :func:`pyPDAF.PDAF.localomi_put_state_lknetf_nondiagR` + + References + ---------- + .. [1] Nerger, L.. (2022) + Data assimilation for nonlinear systems with + a hybrid nonlinear Kalman ensemble transform filter. + Q J R Meteorol Soc, 620–640. doi:10.1002/qj.4221 + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__init_obs_pdaf : Callable + Initialize PE-local observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of the observation vector + + Callback Returns + ---------------- + observation_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + py__init_obs_l_pdaf : Callable + Init. observation vector on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local size of the observation vector + + Callback Returns + ---------------- + observation_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__prodrinva_hyb_l_pdaf : Callable + Provide product R^-1 A on local analysis domain with hybrid weight + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + dim_ens : int + Number of the columns in the matrix processes here. This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize dim. of obs. vector for local ana. domain + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_obs_pdaf : Callable + Restrict full obs. vector to local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_f : int + Size of full observation vector for model sub-domain + dim_obs_l : int + Size of observation vector for local analysis domain + mstate_f : ndarray[np.intc, ndim=1] + Full observation vector for model sub-domain + Array shape: (dim_p) + dim_p : int + Size of full observation vector for model sub-domain + dim_l : int + Size of observation vector for local analysis domain + + Callback Returns + ---------------- + mstate_l : ndarray[np.intc, ndim=1] + Observation vector for local analysis domain + Array shape: (dim_l) + + py__init_obsvar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + meanvar : double + Mean observation error variance + + py__init_obsvar_l_pdaf : Callable + Initialize local mean observation error variance + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Local dimension of observation vector + obs_l : ndarray[np.float64, ndim=1] + Local observation vector + Array shape: (dim_obs_p) + dim_obs_p : int + Dimension of local observation vector + + Callback Returns + ---------------- + meanvar_l : double + Mean local observation error variance + + py__likelihood_l_pdaf : Callable + Compute likelihood + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__likelihood_hyb_l_pdaf : Callable + Compute likelihood with hybrid weight + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.init_obs_pdaf = py__init_obs_pdaf + pdaf_cb.init_obs_l_pdaf = py__init_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.prodrinva_hyb_l_pdaf = py__prodrinva_hyb_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_obs_pdaf = py__g2l_obs_pdaf + pdaf_cb.init_obsvar_pdaf = py__init_obsvar_pdaf + pdaf_cb.init_obsvar_l_pdaf = py__init_obsvar_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.likelihood_hyb_l_pdaf = py__likelihood_hyb_l_pdaf + cdef int outflag + with nogil: + c__pdaflocal_put_state_lknetf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__init_obs_pdaf, + pdaf_cb.c__init_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__prodrinva_hyb_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_obs_pdaf, + pdaf_cb.c__init_obsvar_pdaf, + pdaf_cb.c__init_obsvar_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__likelihood_hyb_l_pdaf, + &outflag) + + return outflag + + diff --git a/pyPDAF/source/src/pyPDAF/PDAFlocal/py.typed b/pyPDAF/source/src/pyPDAF/PDAFlocal/py.typed new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/pyPDAF/source/src/pyPDAF/PDAFlocalomi/__init__.py b/pyPDAF/source/src/pyPDAF/PDAFlocalomi/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..429399a6cf940a7df3bbc5800b8d163edd9d09e8 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFlocalomi/__init__.py @@ -0,0 +1,2 @@ +"""module file for PDAFlocalomi +""" diff --git a/pyPDAF/source/src/pyPDAF/PDAFlocalomi/assim.pxd b/pyPDAF/source/src/pyPDAF/PDAFlocalomi/assim.pxd new file mode 100644 index 0000000000000000000000000000000000000000..9f85dce0ba9df5b93944e9697a622498bbc65a8e --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFlocalomi/assim.pxd @@ -0,0 +1,153 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t +cdef extern void c__pdaflocalomi_assimilate( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocalomi_assimilate_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocalomi_assimilate_lnetf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocalomi_assimilate_lknetf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__prodrinva_hyb_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* , double* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__likelihood_hyb_l_pdaf)(int* , int* , int* , double* , + double* , double* , double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocalomi_assimilate_en3dvar_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocalomi_assimilate_hyb3dvar_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocalomi_assimilate_en3dvar_lestkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocalomi_assimilate_hyb3dvar_lestkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/PDAFlocalomi/assim.pyx b/pyPDAF/source/src/pyPDAF/PDAFlocalomi/assim.pyx new file mode 100644 index 0000000000000000000000000000000000000000..de926e7f25932fc30936a42175295779c8ebe6fd --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFlocalomi/assim.pyx @@ -0,0 +1,2909 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + +try: + import mpi4py + mpi4py.rc.initialize = False +except ImportError: + pass + +# Global error handler +def global_except_hook(exctype, value, traceback): + from traceback import print_exception + try: + import mpi4py.MPI + + if mpi4py.MPI.Is_initialized(): + try: + sys.stderr.write('Uncaught exception was ''detected on rank {}.\n'.format( + mpi4py.MPI.COMM_WORLD.Get_rank())) + print_exception(exctype, value, traceback) + sys.stderr.write("\n") + sys.stderr.flush() + finally: + try: + mpi4py.MPI.COMM_WORLD.Abort(1) + except Exception as e: + sys.stderr.write('MPI Abort failed, this process will hang.\n') + sys.stderr.flush() + raise e + else: + sys.__excepthook__(exctype, value, traceback) + except ImportError: + sys.__excepthook__(exctype, value, traceback) + +sys.excepthook = global_except_hook + +def assimilate(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, py__prepoststep_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__next_observation_pdaf, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaflocalomi_assimilate(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assimilate_nondiagr(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__prepoststep_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prodrinva_l_pdaf, + py__next_observation_pdaf, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__prodrinva_l_pdaf : Callable + Provide product of inverse of R with matrix A + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaflocalomi_assimilate_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_lnetf_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prepoststep_pdaf, py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__likelihood_l_pdaf, + py__next_observation_pdaf, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__likelihood_l_pdaf : Callable + Compute likelihood and apply localization + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaflocalomi_assimilate_lnetf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_lknetf_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prepoststep_pdaf, py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prodrinva_l_pdaf, + py__prodrinva_hyb_l_pdaf, py__likelihood_l_pdaf, + py__likelihood_hyb_l_pdaf, py__next_observation_pdaf, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__prodrinva_hyb_l_pdaf : Callable + Product R^-1 A on local analysis domain with hybrid weight + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + dim_ens : int + Number of the columns in the matrix processes here. This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, dim_ens) + + py__likelihood_l_pdaf : Callable + Compute likelihood and apply localization + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__likelihood_hyb_l_pdaf : Callable + Compute likelihood and apply localization with tempering + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.prodrinva_hyb_l_pdaf = py__prodrinva_hyb_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.likelihood_hyb_l_pdaf = py__likelihood_hyb_l_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaflocalomi_assimilate_lknetf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__prodrinva_hyb_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__likelihood_hyb_l_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_en3dvar_lestkf(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf, int outflag): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf` or + :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + 3DEnVar for a single DA step where the ensemble anomaly + is generated by LESTKF. + The background error covariance matrix is + estimated by ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An LESTKF is used to generate ensemble perturbations. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_en3dvar_lestkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. Starting the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core DA algorithm + 7. py__cvt_ens_pdaf + 8. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__init_obs_pdaf + (if global adaptive forgetting factor is used + `type_forget=1` in :func:`pyPDAF.PDAF.init`) + 5. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise mean ensemble in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local + adaptive forgetting factor + `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + 9. py__prepoststep_state_pdaf + 10. py__distribute_state_pdaf + 11. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf` + and + :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaflocalomi_assimilate_en3dvar_lestkf( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_hyb3dvar_lestkf(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf, int outflag): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf` or + :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Hybrid 3DEnVar for a single DA step where + the background error covariance is hybridised by + a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + LESTKF in this implementation. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_hyb3dvar_lestkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. The iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core DA algorithm + 7. py__cvt_pdaf + 8. py__cvt_ens_pdaf + 9. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__init_obs_pdaf + (if global adaptive forgetting factor + `type_forget=1` in :func:`pyPDAF.PDAF.init`) + 5. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise mean ensemble in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting + factor `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + 10. py__prepoststep_state_pdaf + 11. py__distribute_state_pdaf + 12. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf` + and + :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaflocalomi_assimilate_hyb3dvar_lestkf( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_en3dvar_lestkf_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prodrinva_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prodrinva_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A with localization + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaflocalomi_assimilate_en3dvar_lestkf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_hyb3dvar_lestkf_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prodrinva_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__cvt_pdaf, py__cvt_adj_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdaflocalomi_assimilate_hyb3dvar_lestkf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + diff --git a/pyPDAF/source/src/pyPDAF/PDAFlocalomi/meson.build b/pyPDAF/source/src/pyPDAF/PDAFlocalomi/meson.build new file mode 100644 index 0000000000000000000000000000000000000000..295cfd8f4ea76cb0d537c55d0d6af52643781498 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFlocalomi/meson.build @@ -0,0 +1,23 @@ +pypdaf_sources = files('assim.pyx', + 'put.pyx', + ) + +foreach file :pypdaf_sources + + cython_ext = python.extension_module( + fs.stem(file), + file, + link_with: [pdafc_lib], + dependencies : [mpi, dep_py, blas_dep, fruntime_dep], + include_directories: include_directories([incdir_numpy ]), + c_args: c_cython_args, + link_args: link_args, + cython_args : cython_args, + link_language: 'fortran', + subdir: 'pyPDAF' / 'PDAFlocalomi', + install: true, + install_rpath: '$ORIGIN' + ) +endforeach + +python.install_sources(['__init__.py'], subdir: 'pyPDAF/PDAFlocalomi/') \ No newline at end of file diff --git a/pyPDAF/source/src/pyPDAF/PDAFlocalomi/put.pxd b/pyPDAF/source/src/pyPDAF/PDAFlocalomi/put.pxd new file mode 100644 index 0000000000000000000000000000000000000000..7cd009357aa9d490ea2dda5e290b5e77520ceeb3 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFlocalomi/put.pxd @@ -0,0 +1,137 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t +cdef extern void c__pdaflocalomi_put_state_en3dvar_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocalomi_put_state_hyb3dvar_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocalomi_put_state_en3dvar_lestkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocalomi_put_state_hyb3dvar_lestkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocalomi_put_state( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocalomi_put_state_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocalomi_put_state_lnetf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdaflocalomi_put_state_lknetf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__prodrinva_hyb_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* , double* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__likelihood_hyb_l_pdaf)(int* , int* , int* , double* , + double* , double* , double* ), + int* outflag) noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/PDAFlocalomi/put.pyx b/pyPDAF/source/src/pyPDAF/PDAFlocalomi/put.pyx new file mode 100644 index 0000000000000000000000000000000000000000..9e05e6c9f6386c405f33327369d7489feb0cf87b --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFlocalomi/put.pyx @@ -0,0 +1,2574 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + +try: + import mpi4py + mpi4py.rc.initialize = False +except ImportError: + pass + +# Global error handler +def global_except_hook(exctype, value, traceback): + from traceback import print_exception + try: + import mpi4py.MPI + + if mpi4py.MPI.Is_initialized(): + try: + sys.stderr.write('Uncaught exception was ''detected on rank {}.\n'.format( + mpi4py.MPI.COMM_WORLD.Get_rank())) + print_exception(exctype, value, traceback) + sys.stderr.write("\n") + sys.stderr.flush() + finally: + try: + mpi4py.MPI.COMM_WORLD.Abort(1) + except Exception as e: + sys.stderr.write('MPI Abort failed, this process will hang.\n') + sys.stderr.flush() + raise e + else: + sys.__excepthook__(exctype, value, traceback) + except ImportError: + sys.__excepthook__(exctype, value, traceback) + +sys.excepthook = global_except_hook + +def put_state_en3dvar_lestkf(py__collect_state_pdaf, + py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prepoststep_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf` + or :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + 3DEnVar for a single DA step without post-processing, + distributing analysis, and setting next observation step, + where the ensemble anomaly is generated by LESTKF. + + Compared to :func:`pyPDAF.PDAF.assimilate_en3dvar_lestkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The background error covariance matrix is estimated by ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An LESTKF is used to generate ensemble perturbations. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. Starting the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core DA algorithm + 7. py__cvt_ens_pdaf + 8. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__init_obs_pdaf + (if global adaptive forgetting factor is used + `type_forget=1` in :func:`pyPDAF.PDAF.init`) + 5. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise mean ensemble in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting factor + `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf` + and :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaflocalomi_put_state_en3dvar_lestkf( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_hyb3dvar_lestkf(py__collect_state_pdaf, + py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__prepoststep_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf` + or :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Hybrid 3DEnVar for a single DA step using + non-diagnoal observation error covariance matrix + without post-processing, distributing analysis, + and setting next observation step, where + the background error covariance is hybridised by + a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + + Compared to :func:`pyPDAF.PDAF.assimilate_hyb3dvar_lestkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + LESTKF in this implementation. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. The iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core DA algorithm + 7. py__cvt_pdaf + 8. py__cvt_ens_pdaf + 9. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__init_obs_pdaf + (if global adaptive forgetting factor + `type_forget=1` in :func:`pyPDAF.PDAF.init`) + 5. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise mean ensemble in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting + factor `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf` + and :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaflocalomi_put_state_hyb3dvar_lestkf( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_en3dvar_lestkf_nondiagr(py__collect_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__prodrinva_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaflocalomi_put_state_en3dvar_lestkf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_hyb3dvar_lestkf_nondiagr(py__collect_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__prodrinva_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prodrinva_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdaflocalomi_put_state_hyb3dvar_lestkf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state(py__collect_state_pdaf, py__init_dim_obs_f_pdaf, + py__obs_op_f_pdaf, py__prepoststep_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + with nogil: + c__pdaflocalomi_put_state(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, &outflag) + + return outflag + + +def put_state_nondiagr(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__prepoststep_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__prodrinva_l_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__prodrinva_l_pdaf : Callable + Provide product of inverse of R with matrix A + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + cdef int outflag + with nogil: + c__pdaflocalomi_put_state_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + &outflag) + + return outflag + + +def put_state_lnetf_nondiagr(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__prepoststep_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__likelihood_l_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__likelihood_l_pdaf : Callable + Compute likelihood and apply localization + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + cdef int outflag + with nogil: + c__pdaflocalomi_put_state_lnetf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + &outflag) + + return outflag + + +def put_state_lknetf_nondiagr(py__collect_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__prepoststep_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prodrinva_l_pdaf, + py__prodrinva_hyb_l_pdaf, py__likelihood_l_pdaf, py__likelihood_hyb_l_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__prodrinva_hyb_l_pdaf : Callable + Product R^-1 A on local analysis domain with hybrid weight + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + dim_ens : int + Number of the columns in the matrix processes here. This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, dim_ens) + + py__likelihood_l_pdaf : Callable + Compute likelihood and apply localization + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__likelihood_hyb_l_pdaf : Callable + Compute likelihood and apply localization with tempering + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.prodrinva_hyb_l_pdaf = py__prodrinva_hyb_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.likelihood_hyb_l_pdaf = py__likelihood_hyb_l_pdaf + cdef int outflag + with nogil: + c__pdaflocalomi_put_state_lknetf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__prodrinva_hyb_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__likelihood_hyb_l_pdaf, + &outflag) + + return outflag + + diff --git a/pyPDAF/source/src/pyPDAF/PDAFomi/__init__.py b/pyPDAF/source/src/pyPDAF/PDAFomi/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..66f19cf42ed76340b47e335a3abac250efb5efb9 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFomi/__init__.py @@ -0,0 +1,23 @@ +"""PDAFomi module""" +from ._pdafomi_c import init, init_local, check_error, gather_obs, \ + gather_obsstate, get_interp_coeff_tri, \ + get_interp_coeff_lin1d, get_interp_coeff_lin, \ + init_dim_obs_l_iso, init_dim_obs_l_noniso, \ + init_dim_obs_l_noniso_locweights, obs_op_gridpoint, \ + obs_op_gridavg, obs_op_extern, obs_op_interp_lin, \ + obs_op_adj_gridpoint, obs_op_adj_gridavg, \ + obs_op_adj_interp_lin, observation_localization_weights, \ + set_debug_flag, set_dim_obs_l, set_localization, \ + set_localization_noniso, set_localize_covar_iso, \ + set_localize_covar_noniso, \ + set_localize_covar_noniso_locweights, \ + set_obs_diag, set_domain_limits, \ + get_domain_limits_unstr, store_obs_l_index, \ + store_obs_l_index_vdist +from .diag import diag_dimobs, diag_get_hx, diag_get_hxmean, \ + diag_get_ivar, diag_get_obs, diag_nobstypes, \ + diag_obs_rmsd, diag_stats +from .setter import set_doassim, set_disttype, set_ncoord, \ + set_obs_err_type, set_use_global_obs, \ + set_inno_omit, set_inno_omit_ivar, \ + set_id_obs_p, set_icoeff_p, set_domainsize, set_name \ No newline at end of file diff --git a/pyPDAF/source/src/pyPDAF/PDAFomi/_pdafomi_c.pxd b/pyPDAF/source/src/pyPDAF/PDAFomi/_pdafomi_c.pxd new file mode 100644 index 0000000000000000000000000000000000000000..43c5e75c118669ec7bd957c842c33de32f4db5f1 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFomi/_pdafomi_c.pxd @@ -0,0 +1,114 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t +cdef extern void c__pdafomi_init(int* n_obs) noexcept nogil; + +cdef extern void c__pdafomi_init_local() noexcept nogil; + +cdef extern void c__pdafomi_check_error( + int* flag) noexcept nogil; + +cdef extern void c__pdafomi_gather_obs(int* i_obs, int* dim_obs_p, + CFI_cdesc_t* obs_p, CFI_cdesc_t* ivar_obs_p, CFI_cdesc_t* ocoord_p, + int* ncoord, double* lradius, + int* dim_obs_f) noexcept nogil; + +cdef extern void c__pdafomi_gather_obsstate(int* i_obs, + CFI_cdesc_t* obsstate_p, + CFI_cdesc_t* obsstate_f) noexcept nogil; + +cdef extern void c__pdafomi_get_interp_coeff_tri(CFI_cdesc_t* gpc, + CFI_cdesc_t* oc, CFI_cdesc_t* icoeff) noexcept nogil; + +cdef extern void c__pdafomi_get_interp_coeff_lin1d(CFI_cdesc_t* gpc, + double* oc, CFI_cdesc_t* icoeff) noexcept nogil; + +cdef extern void c__pdafomi_get_interp_coeff_lin(int* num_gp, int* n_dim, + CFI_cdesc_t* gpc, CFI_cdesc_t* oc, + CFI_cdesc_t* icoeff) noexcept nogil; + +cdef extern void c__pdafomi_init_dim_obs_l_iso(int* i_obs, + CFI_cdesc_t* coords_l, int* locweight, double* cradius, + double* sradius, int* cnt_obs_l_all) noexcept nogil; + +cdef extern void c__pdafomi_init_dim_obs_l_noniso(int* i_obs, + CFI_cdesc_t* coords_l, int* locweight, CFI_cdesc_t* cradius, + CFI_cdesc_t* sradius, int* cnt_obs_l_all) noexcept nogil; + +cdef extern void c__pdafomi_init_dim_obs_l_noniso_locweights(int* i_obs, + CFI_cdesc_t* coords_l, CFI_cdesc_t* locweights, CFI_cdesc_t* cradius, + CFI_cdesc_t* sradius, int* cnt_obs_l) noexcept nogil; + +cdef extern void c__pdafomi_obs_op_gridpoint(int* i_obs, + CFI_cdesc_t* state_p, + CFI_cdesc_t* obs_f_all) noexcept nogil; + +cdef extern void c__pdafomi_obs_op_gridavg(int* i_obs, int* nrows, + CFI_cdesc_t* state_p, + CFI_cdesc_t* obs_f_all) noexcept nogil; + +cdef extern void c__pdafomi_obs_op_extern(int* i_obs, + CFI_cdesc_t* ostate_p, + CFI_cdesc_t* obs_f_all) noexcept nogil; + +cdef extern void c__pdafomi_obs_op_interp_lin(int* i_obs, int* nrows, + CFI_cdesc_t* state_p, + CFI_cdesc_t* obs_f_all) noexcept nogil; + +cdef extern void c__pdafomi_obs_op_adj_gridpoint(int* i_obs, + CFI_cdesc_t* obs_f_all, + CFI_cdesc_t* state_p) noexcept nogil; + +cdef extern void c__pdafomi_obs_op_adj_gridavg(int* i_obs, int* nrows, + CFI_cdesc_t* obs_f_all, + CFI_cdesc_t* state_p) noexcept nogil; + +cdef extern void c__pdafomi_obs_op_adj_interp_lin(int* i_obs, int* nrows, + CFI_cdesc_t* obs_f_all, + CFI_cdesc_t* state_p) noexcept nogil; + +cdef extern void c__pdafomi_observation_localization_weights(int* i_obs, + int* ncols, CFI_cdesc_t* a_l, double* weight, + int* verbose) noexcept nogil; + +cdef extern void c__pdafomi_set_debug_flag( + int* debugval) noexcept nogil; + +cdef extern void c__pdafomi_set_dim_obs_l(int* i_obs, int* cnt_obs_l_all, + int* cnt_obs_l) noexcept nogil; + +cdef extern void c__pdafomi_set_localization(int* i_obs, double* cradius, + double* sradius, int* locweight) noexcept nogil; + +cdef extern void c__pdafomi_set_localization_noniso(int* i_obs, + int* nradii, double* cradius, double* sradius, int* locweight, + int* locweight_v) noexcept nogil; + +cdef extern void c__pdafomi_set_localize_covar_iso(int* i_obs, int* dim, + int* ncoords, CFI_cdesc_t* coords, int* locweight, double* cradius, + double* sradius) noexcept nogil; + +cdef extern void c__pdafomi_set_localize_covar_noniso(int* i_obs, int* dim, + int* ncoords, CFI_cdesc_t* coords, int* locweight, + CFI_cdesc_t* cradius, CFI_cdesc_t* sradius) noexcept nogil; + +cdef extern void c__pdafomi_set_localize_covar_noniso_locweights( + int* i_obs, int* dim, int* ncoords, CFI_cdesc_t* coords, + CFI_cdesc_t* locweights, CFI_cdesc_t* cradius, + CFI_cdesc_t* sradius) noexcept nogil; + +cdef extern void c__pdafomi_set_obs_diag( + int* diag) noexcept nogil; + +cdef extern void c__pdafomi_set_domain_limits( + double* lim_coords) noexcept nogil; + +cdef extern void c__pdafomi_get_domain_limits_unstr(int* npoints_p, + CFI_cdesc_t* coords_p) noexcept nogil; + +cdef extern void c__pdafomi_store_obs_l_index(int* i_obs, int* idx, + int* id_obs_l, double* distance, double* cradius_l, + double* sradius_l) noexcept nogil; + +cdef extern void c__pdafomi_store_obs_l_index_vdist(int* i_obs, int* idx, + int* id_obs_l, double* distance, double* cradius_l, double* sradius_l, + double* vdist) noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/PDAFomi/_pdafomi_c.pyi b/pyPDAF/source/src/pyPDAF/PDAFomi/_pdafomi_c.pyi new file mode 100644 index 0000000000000000000000000000000000000000..a8af6468014791fe5c0a2e17275b59278e689036 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFomi/_pdafomi_c.pyi @@ -0,0 +1,915 @@ +# pylint: disable=unused-argument +"""Stub file for PDAFomi module +""" +from typing import Tuple +import numpy as np + + +def init(n_obs:int) -> None: + r"""Allocating an array of `obs_f` derived types instances. + + This function initialises the number of observation types, + which should be called at the start of the DA system + after :func:`pyPDAF.PDAF.init`. + + Parameters + ---------- + n_obs : int + number of observations + """ + +def init_local() -> None: + r"""Allocating an array of `obs_l` derived types instances. + + This function initialises the number of observation types + for each local analysis domain, + which should be called at the start of the local analysis loop + in :func:`py__init_dim_obs_l_pdaf`. + + """ + +def check_error(flag: int) -> int: + r"""This function returns the value of the PDAF-OMI internal error flag. + + Since PDAF-OMI executes internal routines in which errors could occur due to + an inconsistent configuration of the observations. Directly returning + an error flag as a subroutine argument is not always possible. + For this reason there is this separate routine to check for the error flag. + + The errors that are checked by PDAF-OMI relate to the configuration of + the observations, e.g. it is checked whether some dimensions are consistent. + + This can be useful if an error occurred PDAF-OMI also prints an error message, + but it does not stop the program. + + + Parameters + ---------- + flag : int + Error flag + + Returns + ------- + flag : int + Error flag + """ + +def gather_obs(i_obs: int, dim_obs_p: int, obs_p: np.ndarray, + ivar_obs_p: np.ndarray, ocoord_p: np.ndarray, + ncoord: int, lradius: float) -> int: + r"""Gather the dimension of a given type of observation across + multiple local domains/filter processors. + + This function can be used in the user-supplied function of + :func:`py__init_dim_obs_f_pdaf`. + + This function does three things: + 1. Receiving observation dimension on each local process. + 2. Gather the total dimension of given observation type + across local process and the displacement of PE-local + observations relative to the total observation vector + 3. Set the observation vector, observation coordinates, + the inverse of the observation variance, and localisation + radius for this observation type. + + Parameters + ---------- + i_obs : int + index of observation type + dim_obs_p: int + PE-local dimension of observation vector + obs_p : ndarray[tuple[dim_obs_p, ...], np.float64] + PE-local observation vector + The array dimension `dim_obs_p` is dimension of PE-local observation vector + ivar_obs_p : ndarray[tuple[dim_obs_p, ...], np.float64] + PE-local inverse of observation error variance + The array dimension `dim_obs_p` is dimension of PE-local observation vector + ocoord_p : ndarray[tuple[thisobs(i_obs)%ncoord, dim_obs_p, ...], np.float64] + pe-local observation coordinates + The 1st-th dimension dim_obs_p is dimension of PE-local observation vector + ncoord: int + Number of rows of coordinate array + lradius : float + localization radius + + Returns + ------- + dim_obs : int + Full number of observations + """ + +def gather_obsstate(i_obs: int, obsstate_p: np.ndarray, obsstate_f: np.ndarray) -> np.ndarray: + r"""This function is used to implement custom observation operators. + + This function is used inside a custom observation operator. + See also `relevant PDAF wiki page + `_ + + Parameters + ---------- + i_obs : int + index of observations + obsstate_p : ndarray[tuple[thisobs(i_obs)%dim_obs_p, ...], np.float64] + Vector of process-local observed state + obsstate_f : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed vector for all types + The array dimension `nobs_f_all` is dimension of the observation + + Returns + ------- + obsstate_f : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed vector for all types + + The array dimension `nobs_f_all` is dimension of the observation + """ + +def get_interp_coeff_tri(gpc: np.ndarray, oc: np.ndarray, icoeff: np.ndarray) -> np.ndarray: + r"""The coefficient for linear interpolation in 2D on unstructure triangular grid. + + The resulting coefficient is used in :func:`pyPDAF.PDAFomi.obs_op_interp_lin`. + + This function is for triangular model grid interpolation coefficients + determined as barycentric coordinates. + + Parameters + ---------- + gpc : ndarray[tuple[3, 2, ...], np.float64] + Coordinates of grid points with dimension of (3, 2). + 3 grid points surrounding the observation; + each containing lon and lat coordinates. + The order of the grid points in gcoords has to + be consistent with the order of the indices specified in + `id_obs_p` of `obs_f`. + oc : ndarray[tuple[2, ...], np.float64] + Coordinates of observation (targeted location); dim(2) + icoeff : ndarray[tuple[3, ...], np.float64] + Interpolation coefficients; dim(3) + + Returns + ------- + icoeff : ndarray[tuple[3, ...], np.float64] + Interpolation coefficients; dim(3) + + """ + +def get_interp_coeff_lin1d(gpc: np.ndarray, oc: float, icoeff: np.ndarray) -> np.ndarray: + r"""The coefficient for linear interpolation in 1D. + + The resulting coefficient is used in :func:`pyPDAF.PDAFomi.obs_op_interp_lin`. + + Parameters + ---------- + gpc : ndarray[tuple[2, ...], np.float64] + Coordinates of grid points surrounding the observations (dim=2) + oc : float + Coordinates of observation (targeted location) + icoeff : ndarray[tuple[2, ...], np.float64] + Interpolation coefficients (dim=2) + + Returns + ------- + icoeff : ndarray[tuple[2, ...], np.float64] + Interpolation coefficients (dim=2) + + """ + +def get_interp_coeff_lin(num_gp: int, n_dim: int, gpc: np.ndarray, + oc: np.ndarray, icoeff: np.ndarray) -> np.ndarray: + r"""The coefficient for linear interpolation up to 3D. + + The resulting coefficient is used in :func:`pyPDAF.PDAFomi.obs_op_interp_lin`. + + See introduction in `relevant PDAF-OMI wiki page + `_ + + Parameters + ---------- + num_gp: int + Number of grid points used in interpolation + n_dim: int + Number of dimensions in interpolation + gpc : ndarray[tuple[num_gp, n_dim, ...], np.float64] + Coordinates of grid points + The order of the grid points in gcoords has to + be consistent with the order of the indices specified in + `id_obs_p` of `obs_f`. shape: (num_gp, n_dim) + oc : ndarray[tuple[n_dim, ...], np.float64] + Coordinates of observation. shape: (n_dim) + icoeff : ndarray[tuple[num_gp, ...], np.float64] + Interpolation coefficients. shape: (num_gp) + + Returns + ------- + icoeff : ndarray[tuple[num_gp, ...], np.float64] + Interpolation coefficients. shape: (num_gp) + + The array dimension `num_gp` is Length of icoeff + """ + +def init_dim_obs_l_iso(i_obs: int, coords_l: np.ndarray, locweight: int, + cradius: float, sradius: float, cnt_obs_l_all: int) -> int: + r"""Initialize the observation information corresponding to an isotropic local analysis domain. + + One can set localization parameters, like the localization radius, for each observation type. + + The function has to be called in user-supplied function of + `init_dim_obs_l_OBTYPE` in each observation module if a + domain-localized filter (LESTKF/LETKF/LNETF/LSEIK)is used. + + It initialises the local observation information for PDAF-OMI for a + single local analysis domain. This is used for isotropic localisation + where the localisation radius is the same in all directions. + + See also `relevant PDAF wiki page + `_ + + Parameters + ---------- + i_obs : int + index of observation type + coords_l : ndarray[tuple[ncoord, ...], np.float64] + Coordinates of current analysis domain + The array dimension `ncoord` is number of coordinate dimension + locweight : int + Types of localization function + 0) unit weight; 1) exponential; 2) 5-th order polynomial; + 3) 5-th order polynomial with regulatioin using mean variance; + 4) 5-th order polynomial with regulatioin using variance of single observation point; + cradius : float + Vector of localization cut-off radii; observation weight=0 if distance > cradius + sradius : float + Vector of support radii of localization function. + It has no impact if locweight=0; weight = exp(-d / sradius) if locweight=1; + weight = 0 if d >= sradius else f(sradius, distance) if locweight in [2,3,4]. + cnt_obs_l_all : int + Local dimension of current observation vector + + Returns + ------- + cnt_obs_l_all : int + Local dimension of current observation vector + """ + + +def init_dim_obs_l_noniso(i_obs: int, coords_l: np.ndarray, locweight: int, + cradius: np.ndarray, sradius: np.ndarray, + cnt_obs_l_all: int) -> int: + r"""Initialize the observation information corresponding to a non-isotropic + local analysis domain. + + One can set localization parameters, like the localization radius, for + each observation type. + + Here, each dimension can use a different localisation radius. + + The function has to be called in user-supplied function of + `init_dim_obs_l_OBTYPE` in each observation module if a + domain-localized filter (LESTKF/LETKF/LNETF/LSEIK)is used. + + It initialises the local observation information for PDAF-OMI for a + single local analysis domain. This is used for isotropic localisation + where the localisation radius is the same in all directions. + + See also `relevant PDAF wiki page + `_ + as well as `non-isotropic localisation page + `_ + + Parameters + ---------- + i_obs : int + index of observation type + coords_l : ndarray[tuple[ncoord, ...], np.float64] + Coordinates of current analysis domain + The array dimension `ncoord` is number of coordinate dimension + locweight : int + Types of localization function + 0) unit weight; 1) exponential; 2) 5-th order polynomial; + 3) 5-th order polynomial with regulatioin using mean variance; + 4) 5-th order polynomial with regulatioin using variance of single observation point; + cradius : ndarray[tuple[ncoord, ...], np.float64] + Vector of localization cut-off radii; observation weight=0 if distance > cradius + The array dimension `ncoord` is number of coordinate dimension + sradius : ndarray[tuple[ncoord, ...], np.float64] + Vector of support radii of localization function. + It has no impact if locweight=0; weight = exp(-d / sradius) if locweight=1; + weight = 0 if d >= sradius else f(sradius, distance) if locweight in [2,3,4]. + The array dimension `ncoord` is number of coordinate dimension + cnt_obs_l_all : int + Local dimension of current observation vector + + Returns + ------- + cnt_obs_l_all : int + Local dimension of current observation vector + """ + +def init_dim_obs_l_noniso_locweights(i_obs: int, coords_l: np.ndarray, + locweights: np.ndarray, cradius: np.ndarray, + sradius: np.ndarray, cnt_obs_l: int) -> int: + r"""Initialize the observation information corresponding to a non-isotropic + local analysis domain. + + One can set localization parameters, like the localization radius, for each + observation type. + + Here, each dimension can use a different localisation radius and a different + localisation weight. + + The function has to be called in user-supplied function of + `init_dim_obs_l_OBTYPE` in each observation module if a + domain-localized filter (LESTKF/LETKF/LNETF/LSEIK)is used. + + It initialises the local observation information for PDAF-OMI for a + single local analysis domain. This is used for isotropic localisation + where the localisation radius is the same in all directions. + + See also `relevant PDAF wiki page + `_ + as well as `non-isotropic localisation page + `_ + + Parameters + ---------- + i_obs : int + index of observation type + coords_l : ndarray[tuple[ncoord, ...], np.float64] + Coordinates of current analysis domain + The array dimension `ncoord` is number of coordinate dimension + locweights : ndarray[tuple[2, ...], np.intc] + Types of localization function + - 0) unit weight; 1) exponential; 2) 5-th order polynomial; + - 3) 5-th order polynomial with regulatioin using mean variance; + - 4) 5-th order polynomial with regulatioin using variance of single observation point; + The first dimension is horizontal weight function and the second is the vertical function + cradius : ndarray[tuple[ncoord, ...], np.float64] + Vector of localization cut-off radii for each dimension; observation + weight=0 if distance > cradius + The array dimension `ncoord` is number of coordinate dimension + sradius : ndarray[tuple[ncoord, ...], np.float64] + Vector of support radii of localization function for each dimension. + It has no impact if locweight=0; weight = exp(-d / sradius) if locweight=1; + weight = 0 if d >= sradius else f(sradius, distance) if locweight in [2,3,4]. + The array dimension `ncoord` is number of coordinate dimension + cnt_obs_l : int + Local dimension of current observation vector + + Returns + ------- + cnt_obs_l : int + Local dimension of current observation vector + """ + +def obs_op_gridpoint(i_obs: int, state_p: np.ndarray, + obs_f_all: np.ndarray) -> np.ndarray: + r"""A (partial) identity observation operator + + This observation operator is used + when observations and model use the same grid. + + The observations operator selects state vectors + where observations are present based on properties given + in `obs_f`, e.g., `id_obs_p`. + + The function is used in + the user-supplied function :func:`pyPDAF.c__obs_op_pdaf`. + + Parameters + ---------- + i_obs : int + index of observations + state_p : ndarray[tuple[dim_p, ...], np.float64] + PE-local model state (dim_p) + The array dimension `dim_p` is dimension of model state + obs_f_all : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed state for all observation types (nobs_f_all) + The array dimension `nobs_f_all` is dimension of the observation + + Returns + ------- + obs_f_all : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed state for all observation types (nobs_f_all) + + The array dimension `nobs_f_all` is dimension of the observation + """ + +def obs_op_gridavg(i_obs: int, nrows: int, state_p: np.ndarray, + obs_f_all: np.ndarray) -> np.ndarray: + r"""Observation operator that average values on given model grid points. + + The averaged model grid points are specified in `id_obs_p` property of `obs_f`, + which can be set in :func:`pyPDAF.PDAF.omi_set_id_obs_p`. + + The function is used in the user-supplied function `py__obs_op_pdaf`. + + Parameters + ---------- + i_obs : int + index of observations + nrows : int + Number of values to be averaged + state_p : ndarray[tuple[dim_p, ...], np.float64] + PE-local model state (dim_p) + The array dimension `dim_p` is dimension of model state + obs_f_all : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed state for all observation types (nobs_f_all) + The array dimension `nobs_f_all` is dimension of the observation + + Returns + ------- + obs_f_all : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed state for all observation types (nobs_f_all) + + The array dimension `nobs_f_all` is dimension of the observation + """ + +def obs_op_extern(i_obs: int, ostate_p: np.ndarray, obs_f_all: np.ndarray) -> np.ndarray: + """Observation operator for given observed model state. + + Application of observation operator for the case that + a user performs the actual observation operator elsewhere, + e.g., directly in the model during the forecast or offline. + For this case, the user can provide the observed model state + to this routine and it will just call :func:`pyPDAF.PDAFomi.gather_obsstate`, + to obtain the full observed vector `obs_f_all`. + + This has to be called in all filter processes. + + Parameters + ---------- + i_obs : int + index into observation arrays + ostate_p : ndarray[np.float64, ndim=1] + PE-local observed model state + Array shape: (:) + obs_f_all : ndarray[np.float64, ndim=1] + Full observed model state for all observation types + Array shape: (:) + + Returns + ------- + obs_f_all : ndarray[np.float64, ndim=1] + Full observed state for all observation types + Array shape: (:) + """ + +def obs_op_interp_lin(i_obs: int, nrows: int, state_p: np.ndarray, + obs_f_all: np.ndarray) -> np.ndarray: + r"""Observation operator that linearly interpolates model grid values to observation location. + + The grid points used by linear interpolation is specified in `id_obs_p` of `obs_f`, + which can be set by :func:`pyPDAF.PDAFomi.set_id_obs_p`. + + The function also requires `icoeff_p` attribute of `obs_f`, + which can be set by :func:`pyPDAF.PDAFomi.set_icoeff_p` + + The interpolation coefficient can be obtained by :func:`pyPDAF.PDAFomi.get_interp_coeff_lin1D`, + :func:`pyPDAF.PDAFomi.get_interp_coeff_lin`, and + :func:`pyPDAF.PDAFomi.get_interp_coeff_tri` + + The details of interpolation setup can be found at + `relevant PDAF wiki page + `_ + + The function is used in the user-supplied function `py__obs_op_pdaf`. + + Parameters + ---------- + i_obs : int + index of observations + nrows : int + Number of values to be averaged + state_p : ndarray[tuple[dim_p, ...], np.float64] + PE-local model state (dim_p) + The array dimension `dim_p` is dimension of model state + obs_f_all : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed state for all observation types (nobs_f_all) + The array dimension `nobs_f_all` is dimension of the observation + + Returns + ------- + obs_f_all : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed state for all observation types (nobs_f_all) + + The array dimension `nobs_f_all` is dimension of the observation + """ + +def obs_op_adj_gridpoint(i_obs: int, obs_f_all: np.ndarray, + state_p: np.ndarray) -> np.ndarray: + r"""The adjoint observation operator of :func:`pyPDAF.PDAFomi.obs_op_gridpoint`. + + This function performs :math:`\mathbf{H}^\mathrm{T}\mathbf{y}`, + where :math:`\mathbf{H}` is the observation operator and + :math:`\mathbf{y}` is any state in observation space. + + Here :math:`\mathbf{H}` is :func:`pyPDAF.PDAFomi.obs_op_gridpoint`. + + Parameters + ---------- + i_obs : int + index of observations + obs_f_all : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed state for all observation types (nobs_f_all) + The array dimension `nobs_f_all` is dimension of the observation + state_p : ndarray[tuple[dim_p, ...], np.float64] + PE-local model state (dim_p) + The array dimension `dim_p` is dimension of model state + + Returns + ------- + state_p : ndarray[tuple[dim_p, ...], np.float64] + :math:`\mathbf{H}^\mathrm{T}\mathbf{y}` + PE-local model state (dim_p) + The array dimension `dim_p` is dimension of model state + """ + +def obs_op_adj_gridavg(i_obs: int, nrows: int, obs_f_all: np.ndarray, + state_p: np.ndarray) -> np.ndarray: + r"""The adjoint observation operator of :func:`pyPDAF.PDAFomi.obs_op_gridavg`. + + This function performs :math:`\mathbf{H}^\mathrm{T}\mathbf{y}`, + where :math:`\mathbf{H}` is the observation operator and + :math:`\mathbf{y}` is any state in observation space. + + Here :math:`\mathbf{H}` is :func:`pyPDAF.PDAFomi.obs_op_gridavg`. + + Parameters + ---------- + i_obs : int + index of observations + nrows : int + Number of values to be averaged + obs_f_all : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed state for all observation types (nobs_f_all) + The array dimension `nobs_f_all` is dimension of the observation + state_p : ndarray[tuple[dim_p, ...], np.float64] + PE-local model state (dim_p) + The array dimension `dim_p` is dimension of model state + + Returns + ------- + state_p : ndarray[tuple[dim_p, ...], np.float64] + :math:`\mathbf{H}^\mathrm{T}\mathbf{y}` + PE-local model state (dim_p) + The array dimension `dim_p` is dimension of model state + """ + +def obs_op_adj_interp_lin(i_obs: int, nrows: int, obs_f_all: np.ndarray, + state_p: np.ndarray) -> np.ndarray: + r"""The adjoint observation operator of :func:`pyPDAF.PDAFomi.obs_op_interp_lin`. + + This function performs :math:`\mathbf{H}^\mathrm{T}\mathbf{y}`, + where :math:`\mathbf{H}` is the observation operator and + :math:`\mathbf{y}` is any state in observation space. + + Here :math:`\mathbf{H}` is :func:`pyPDAF.PDAFomi.obs_op_interp_lin`. + + Parameters + ---------- + i_obs : int + index of observations + nrows : int + Number of values to be averaged + obs_f_all : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed state for all observation types (nobs_f_all) + The array dimension `nobs_f_all` is dimension of the observation + state_p : ndarray[tuple[dim_p, ...], np.float64] + PE-local model state (dim_p) + The array dimension `dim_p` is dimension of model state + + Returns + ------- + state_p : ndarray[tuple[dim_p, ...], np.float64] + :math:`\mathbf{H}^\mathrm{T}\mathbf{y}` + PE-local model state (dim_p) + The array dimension `dim_p` is dimension of model state + """ + +def observation_localization_weights(i_obs: int, ncols: int, a_l: np.ndarray, + dim_obs_l: int, verbose: int) -> np.ndarray: + r"""Returns a vector of observation localisation weights. + + The weights are based on specifications given by localisation setups and + observation coordinates in OMI. This function is used in the case of + non-diagonal observation error covariance matrix where one has to perform + localisation in user-supplied functions, e.g., + :func:`pyPDAF.c__prodrinva_pdaf` or :func:`pyPDAF.c__likelihood_l_pdaf`. + + Here, `a_l` is typically the input array in :func:`pyPDAF.c__prodrinva_pdaf`. + + Parameters + ---------- + i_obs : int + index into observation arrays + ncols : int + Rank of initial covariance matrix + a_l : ndarray[np.float64, ndim=2] + Input matrix (thisobs_l%dim_obs_l, ncols) + Array shape: (:, :) + dim_obs_l : int + Dimension of local observation vector of the i_obs-th observation type + verbose : int + Verbosity flag + + Returns + ------- + weight : ndarray[np.float64, ndim=1] + > Localization weights + Array shape: (thisobs_l(i_obs)%dim_obs_l) + """ + +def set_debug_flag(debugval: int) -> None: + """Activate the debug output of the PDAFomi. + + Starting from the use of this function, + the debug infomation is sent to screen output. + The screen output end when the debug flag is + set to 0 by this function. + + See also `relevant PDAF wiki page `_ + + Parameters + ---------- + debugval : int + Value for debugging flag + """ + +def set_dim_obs_l(i_obs: int, cnt_obs_l_all: int, cnt_obs_l: int) -> Tuple[int, int]: + """Stores the local number of observations for OMI-internal initialisations. + + This is used for alternative to :func:`pyPDF.PDAFomi.init_dim_obs_l`. + + See more details in `relevant PDAF wiki page + `_ + + Parameters + ---------- + i_obs : int + index into observation arrays + cnt_obs_l_all : int + Local dimension of observation vector over all obs. types + cnt_obs_l : int + Local dimension of single observation type vector + + Returns + ------- + cnt_obs_l_all : int + Local dimension of observation vector over all obs. types + cnt_obs_l : int + Local dimension of single observation type vector + """ + +def set_localization(i_obs: int, cradius: float, sradius: float, locweight: int) -> None: + r"""Stores the isotropic localization parameters (cradius, sradius, locweight) in OMI. + + This is used for alternative to :func:`pyPDF.PDAFomi.init_dim_obs_l`. + + See more details in `relevant PDAF wiki page + `_ + + + Parameters + ---------- + i_obs : int + index into observation arrays + cradius : double + Localization cut-off radius + sradius : double + Support radius of localization function + locweight : int + Type of localization function + """ + +def set_localization_noniso(i_obs: int, nradii: int, cradius: np.ndarray, + sradius: np.ndarray, locweight: int, locweight_v: int) -> None: + r"""Stores the non-isotropic localization parameters (cradius, sradius, locweight) in OMI. + + This is used for alternative to :func:`pyPDF.PDAFomi.init_dim_obs_l`. + + See more details in `relevant PDAF wiki page + `_ + + + + Parameters + ---------- + i_obs : int + index into observation arrays + nradii : int + Number of radii to consider for localization + cradius : ndarray[np.float64, ndim=1] + Localization cut-off radius + Array shape: (nradii) + sradius : ndarray[np.float64, ndim=1] + Support radius of localization function + Array shape: (nradii) + locweight : int + Type of localization function + locweight_v : int + Type of localization function in vertical direction (only for nradii=3) + + Returns + ------- + """ + +def set_localize_covar_iso(i_obs: int, dim: int, ncoords: int, coords: np.ndarray, + locweight: int, cradius: float, sradius: float) -> None: + r"""Initialise local observation information for isotropic covariance localisation. + + This is used in stochastic EnKF/EAKF/EnSRF. This is called in user-supplied functions + :func:`pyPDAF.c__init_dim_obs_pdaf`. + + Parameters + ---------- + i_obs : int + index into observation arrays + dim : int + State dimension + ncoords : int + number of coordinate directions + coords : ndarray[np.float64, ndim=2] + Coordinates of state vector elements + Array shape: (:,:) + locweight : int + Localization weight type + cradius : double + localization radius + sradius : double + support radius for weight functions + """ + +def set_localize_covar_noniso(i_obs: int, dim: int, ncoords: int, + coords: np.ndarray, locweight: int, + cradius: np.ndarray, sradius: np.ndarray) -> None: + r"""Initialise local observation information for non-isotropic covariance localisation. + + This is used in stochastic EnKF/EAKF/EnSRF. This is called in user-supplied functions + :func:`pyPDAF.c__init_dim_obs_pdaf`. + + Here, localisation radii differ for each spatial dimension. + + Parameters + ---------- + i_obs : int + index into observation arrays + dim : int + State dimension + ncoords : int + number of coordinate directions + coords : ndarray[np.float64, ndim=2] + Coordinates of state vector elements + Array shape: (:,:) + locweight : int + Localization weight type + cradius : ndarray[np.float64, ndim=1] + Vector of localization cut-off radii + Array shape: (:) + sradius : ndarray[np.float64, ndim=1] + Vector of support radii of localization function + Array shape: (:) + """ + +def set_localize_covar_noniso_locweights(i_obs: int, dim: int, ncoords: int, + coords: np.ndarray, locweights: np.ndarray, + cradius: np.ndarray, sradius: np.ndarray) -> None: + r"""Initialise local observation information for non-isotropic covariance localisation. + + This is used in stochastic EnKF/EAKF/EnSRF. This is called in user-supplied functions + :func:`pyPDAF.c__init_dim_obs_pdaf`. + + Here, both weighting function and localisation radii differ for each spatial dimension. + + Parameters + ---------- + i_obs : int + index into observation arrays + dim : int + State dimension + ncoords : int + number of coordinate directions + coords : ndarray[np.float64, ndim=2] + Coordinates of state vector elements + Array shape: (:,:) + locweights : ndarray[np.intc, ndim=1] + Types of localization function + Array shape: (:) + cradius : ndarray[np.float64, ndim=1] + Vector of localization cut-off radii + Array shape: (:) + sradius : ndarray[np.float64, ndim=1] + Vector of support radii of localization function + Array shape: (:) + """ + +def set_obs_diag(diag: int) -> None: + """Activate or deactivate the observation diagnostics. + + By default, observation diagnostics are activated that stores + additional information for diagnostics. + However, as this functionality increases the required memory, + it might be desirable to deactivate this functionality. + + This function is used deactivate the observation diagnostics. + Once deactivated, one cannot use diagnostics in :mod:`pyPDAF.PDAFomi.diag`. + It is also possible to re-activate the observation diagnostics at a later time. + + The function can be called by all processes, but it is sufficient to call it + for those processes that handle observations, which usually are the filter processes. + + This function can be called after the initialization of PDAF in `pyPDAF.PDAF.init`. + + + Parameters + ---------- + diag : int + Value for observation diagnostics mode + - > 0: activates observation diagnostics + - 0: deactivates observation diagnostics + """ + +def set_domain_limits(lim_coords: np.ndarray) -> None: + r"""Set the domain limits for domain decomposed local domain. + + This is for the use of :func:`pyPDAF.PDAFomi.set_use_global_obs`. + Currently, it only supports 2D limitations. + + See `relevant PDAF wiki page + `_ + + + Parameters + ---------- + lim_coords : ndarray[tuple[2, 2, ...], np.float64] + geographic coordinate array (1: longitude, 2: latitude) + """ + +def get_domain_limits_unstr(npoints_p: int, coords_p: np.ndarray) -> None: + r"""Set the domain limits for unstructured domain decomposed local domain. + + This is for the use of :func:`pyPDAF.PDAFomi.set_use_global_obs`. + Currently, it only supports 2D limitations. + + See also `relevant PDAF wiki page + `_ + + Parameters + ---------- + npoints_p : int + number of process-local grid points + coords_p : ndarray[np.float64, ndim=2] + geographic coordinate array, dimension (2, npoints_p) + (row 1: longitude, 2: latitude) + ranges: longitude (-pi, pi), latitude (-pi/2, pi/2) + Array shape: (:,:) + """ + +def store_obs_l_index(i_obs: int, idx: int, id_obs_l: int, distance: float, + cradius_l: float, sradius_l: float) -> None: + r"""Save local observation information in PDAF. + + One should check `relevant PDAF wiki page + `_ + before using this function. + + Parameters + ---------- + i_obs : int + index into observation arrays + idx : int + index of the valid local observations in current local analysis domain + id_obs_l : int + Index of local observation in full observation array + distance : double + Distance between local analysis domain and observation + cradius_l : double + cut-off radius for this local observation + sradius_l : double + support radius for this local observation + """ + +def store_obs_l_index_vdist(i_obs: int, idx: int, id_obs_l: int, distance: float, + cradius_l: float, sradius_l: float, vdist: float) -> None: + r"""Save local observation information for 2+1D factorized localization + in the vertical direction in PDAF. + + One should check `relevant PDAF wiki page + `_ + before using this function. + + Parameters + ---------- + i_obs : int + index into observation arrays + idx : int + index of the valid local observations in current local analysis domain + id_obs_l : int + Index of local observation in full observation array + distance : double + Distance between local analysis domain and observation + cradius_l : double + cut-off radius for this local observation + sradius_l : double + support radius for this local observation + vdist : double + support radius in vertical direction for 2+1D factorized localization + """ diff --git a/pyPDAF/source/src/pyPDAF/PDAFomi/_pdafomi_c.pyx b/pyPDAF/source/src/pyPDAF/PDAFomi/_pdafomi_c.pyx new file mode 100644 index 0000000000000000000000000000000000000000..7ae55a9baed2a19e7167dde08ab9a8c739b1dac3 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFomi/_pdafomi_c.pyx @@ -0,0 +1,1510 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + +def init(int n_obs): + r"""init(n_obs:int) -> None + + Allocating an array of `obs_f` derived types instances. + + This function initialises the number of observation types, + which should be called at the start of the DA system + after :func:`pyPDAF.PDAF.init`. + + Parameters + ---------- + n_obs : int + number of observations + """ + with nogil: + c__pdafomi_init(&n_obs) + + + +def init_local(): + r"""init_local() -> None + + Allocating an array of `obs_l` derived types instances. + + This function initialises the number of observation types + for each local analysis domain, + which should be called at the start of the local analysis loop + in :func:`py__init_dim_obs_l_pdaf`. + + """ + with nogil: + c__pdafomi_init_local() + + + +def check_error(int flag): + r"""check_error(flag: int) -> int + + This function returns the value of the PDAF-OMI internal error flag. + + Since PDAF-OMI executes internal routines in which errors could occur due to + an inconsistent configuration of the observations. Directly returning + an error flag as a subroutine argument is not always possible. + For this reason there is this separate routine to check for the error flag. + + The errors that are checked by PDAF-OMI relate to the configuration of + the observations, e.g. it is checked whether some dimensions are consistent. + + This can be useful if an error occurred PDAF-OMI also prints an error message, + but it does not stop the program. + + + Parameters + ---------- + flag : int + Error flag + + Returns + ------- + flag : int + Error flag + """ + with nogil: + c__pdafomi_check_error(&flag) + + return flag + + +def gather_obs(int i_obs, int dim_obs_p, double[::1] obs_p, + double[::1] ivar_obs_p, double[::1,:] ocoord_p, int ncoord, + double lradius): + r"""gather_obs(i_obs: int, dim_obs_p: int, obs_p: np.ndarray, ivar_obs_p: np.ndarray, ocoord_p: np.ndarray, ncoord: int, lradius: float) -> int + + Gather the dimension of a given type of observation across + multiple local domains/filter processors. + + This function can be used in the user-supplied function of + :func:`py__init_dim_obs_f_pdaf`. + + This function does three things: + 1. Receiving observation dimension on each local process. + 2. Gather the total dimension of given observation type + across local process and the displacement of PE-local + observations relative to the total observation vector + 3. Set the observation vector, observation coordinates, + the inverse of the observation variance, and localisation + radius for this observation type. + + Parameters + ---------- + i_obs : int + index of observation type + dim_obs_p: int + PE-local dimension of observation vector + obs_p : ndarray[tuple[dim_obs_p, ...], np.float64] + PE-local observation vector + The array dimension `dim_obs_p` is dimension of PE-local observation vector + ivar_obs_p : ndarray[tuple[dim_obs_p, ...], np.float64] + PE-local inverse of observation error variance + The array dimension `dim_obs_p` is dimension of PE-local observation vector + ocoord_p : ndarray[tuple[thisobs(i_obs)%ncoord, dim_obs_p, ...], np.float64] + pe-local observation coordinates + The 1st-th dimension dim_obs_p is dimension of PE-local observation vector + ncoord: int + Number of rows of coordinate array + lradius : float + localization radius + + Returns + ------- + dim_obs : int + Full number of observations + """ + cdef CFI_cdesc_rank1 obs_p_cfi + cdef CFI_cdesc_t *obs_p_ptr = &obs_p_cfi + cdef size_t obs_p_nbytes = obs_p.nbytes + cdef CFI_index_t obs_p_extent[1] + obs_p_extent[0] = obs_p.shape[0] + cdef CFI_cdesc_rank1 ivar_obs_p_cfi + cdef CFI_cdesc_t *ivar_obs_p_ptr = &ivar_obs_p_cfi + cdef size_t ivar_obs_p_nbytes = ivar_obs_p.nbytes + cdef CFI_index_t ivar_obs_p_extent[1] + ivar_obs_p_extent[0] = ivar_obs_p.shape[0] + cdef CFI_cdesc_rank2 ocoord_p_cfi + cdef CFI_cdesc_t *ocoord_p_ptr = &ocoord_p_cfi + cdef size_t ocoord_p_nbytes = ocoord_p.nbytes + cdef CFI_index_t ocoord_p_extent[2] + ocoord_p_extent[0] = ocoord_p.shape[0] + ocoord_p_extent[1] = ocoord_p.shape[1] + cdef int dim_obs_f + with nogil: + CFI_establish(obs_p_ptr, &obs_p[0], CFI_attribute_other, + CFI_type_double , obs_p_nbytes, 1, obs_p_extent) + + CFI_establish(ivar_obs_p_ptr, &ivar_obs_p[0], CFI_attribute_other, + CFI_type_double , ivar_obs_p_nbytes, 1, ivar_obs_p_extent) + + CFI_establish(ocoord_p_ptr, &ocoord_p[0,0], CFI_attribute_other, + CFI_type_double , ocoord_p_nbytes, 2, ocoord_p_extent) + + c__pdafomi_gather_obs(&i_obs, &dim_obs_p, obs_p_ptr, + ivar_obs_p_ptr, ocoord_p_ptr, &ncoord, + &lradius, &dim_obs_f) + + return dim_obs_f + + +def gather_obsstate(int i_obs, double [::1] obsstate_p, + double [::1] obsstate_f): + r"""gather_obsstate(i_obs: int, obsstate_p: np.ndarray, obsstate_f: np.ndarray) -> np.ndarray + + This function is used to implement custom observation operators. + + This function is used inside a custom observation operator. + See also `relevant PDAF wiki page `_ + + Parameters + ---------- + i_obs : int + index of observations + obsstate_p : ndarray[tuple[thisobs(i_obs)%dim_obs_p, ...], np.float64] + Vector of process-local observed state + obsstate_f : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed vector for all types + The array dimension `nobs_f_all` is dimension of the observation + + Returns + ------- + obsstate_f : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed vector for all types + + The array dimension `nobs_f_all` is dimension of the observation + """ + cdef CFI_cdesc_rank1 obsstate_f_cfi + cdef CFI_cdesc_t *obsstate_f_ptr = &obsstate_f_cfi + cdef size_t obsstate_f_nbytes = obsstate_f.nbytes + cdef CFI_index_t obsstate_f_extent[1] + obsstate_f_extent[0] = obsstate_f.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obsstate_f_np = np.asarray(obsstate_f, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 obsstate_p_cfi + cdef CFI_cdesc_t *obsstate_p_ptr = &obsstate_p_cfi + cdef size_t obsstate_p_nbytes = obsstate_p.nbytes + cdef CFI_index_t obsstate_p_extent[1] + obsstate_p_extent[0] = obsstate_p.shape[0] + with nogil: + CFI_establish(obsstate_p_ptr, &obsstate_p[0], CFI_attribute_other, + CFI_type_double , obsstate_p_nbytes, 1, obsstate_p_extent) + + CFI_establish(obsstate_f_ptr, &obsstate_f[0], CFI_attribute_other, + CFI_type_double , obsstate_f_nbytes, 1, obsstate_f_extent) + + c__pdafomi_gather_obsstate(&i_obs, obsstate_p_ptr, obsstate_f_ptr) + + return obsstate_f_np + + +def get_interp_coeff_tri(double [::1,:] gpc, double [::1] oc, + double [::1] icoeff): + r"""get_interp_coeff_tri(gpc: np.ndarray, oc: np.ndarray, icoeff: np.ndarray) -> np.ndarray + + The coefficient for linear interpolation in 2D on unstructure triangular grid. + + The resulting coefficient is used in :func:`pyPDAF.PDAFomi.obs_op_interp_lin`. + + This function is for triangular model grid interpolation coefficients determined as barycentric coordinates. + + Parameters + ---------- + gpc : ndarray[tuple[3, 2, ...], np.float64] + Coordinates of grid points with dimension of (3, 2). + 3 grid points surrounding the observation; + each containing lon and lat coordinates. + The order of the grid points in gcoords has to + be consistent with the order of the indices specified in + `id_obs_p` of `obs_f`. + oc : ndarray[tuple[2, ...], np.float64] + Coordinates of observation (targeted location); dim(2) + icoeff : ndarray[tuple[3, ...], np.float64] + Interpolation coefficients; dim(3) + + Returns + ------- + icoeff : ndarray[tuple[3, ...], np.float64] + Interpolation coefficients; dim(3) + + """ + cdef CFI_cdesc_rank1 icoeff_cfi + cdef CFI_cdesc_t *icoeff_ptr = &icoeff_cfi + cdef size_t icoeff_nbytes = icoeff.nbytes + cdef CFI_index_t icoeff_extent[1] + icoeff_extent[0] = icoeff.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] icoeff_np = np.asarray(icoeff, dtype=np.float64, order="F") + cdef CFI_cdesc_rank2 gpc_cfi + cdef CFI_cdesc_t *gpc_ptr = &gpc_cfi + cdef size_t gpc_nbytes = gpc.nbytes + cdef CFI_index_t gpc_extent[2] + gpc_extent[0] = gpc.shape[0] + gpc_extent[1] = gpc.shape[1] + cdef CFI_cdesc_rank1 oc_cfi + cdef CFI_cdesc_t *oc_ptr = &oc_cfi + cdef size_t oc_nbytes = oc.nbytes + cdef CFI_index_t oc_extent[1] + oc_extent[0] = oc.shape[0] + with nogil: + CFI_establish(gpc_ptr, &gpc[0,0], CFI_attribute_other, + CFI_type_double , gpc_nbytes, 2, gpc_extent) + + CFI_establish(oc_ptr, &oc[0], CFI_attribute_other, + CFI_type_double , oc_nbytes, 1, oc_extent) + + CFI_establish(icoeff_ptr, &icoeff[0], CFI_attribute_other, + CFI_type_double , icoeff_nbytes, 1, icoeff_extent) + + c__pdafomi_get_interp_coeff_tri(gpc_ptr, oc_ptr, icoeff_ptr) + + return icoeff_np + + +def get_interp_coeff_lin1d(double [::1] gpc, double oc, double [::1] icoeff): + r"""get_interp_coeff_lin1d(gpc: np.ndarray, oc: float, icoeff: np.ndarray) -> np.ndarray + + The coefficient for linear interpolation in 1D. + + The resulting coefficient is used in :func:`pyPDAF.PDAFomi.obs_op_interp_lin`. + + Parameters + ---------- + gpc : ndarray[tuple[2, ...], np.float64] + Coordinates of grid points surrounding the observations (dim=2) + oc : float + Coordinates of observation (targeted location) + icoeff : ndarray[tuple[2, ...], np.float64] + Interpolation coefficients (dim=2) + + Returns + ------- + icoeff : ndarray[tuple[2, ...], np.float64] + Interpolation coefficients (dim=2) + + """ + cdef CFI_cdesc_rank1 icoeff_cfi + cdef CFI_cdesc_t *icoeff_ptr = &icoeff_cfi + cdef size_t icoeff_nbytes = icoeff.nbytes + cdef CFI_index_t icoeff_extent[1] + icoeff_extent[0] = icoeff.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] icoeff_np = np.asarray(icoeff, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 gpc_cfi + cdef CFI_cdesc_t *gpc_ptr = &gpc_cfi + cdef size_t gpc_nbytes = gpc.nbytes + cdef CFI_index_t gpc_extent[1] + gpc_extent[0] = gpc.shape[0] + with nogil: + CFI_establish(gpc_ptr, &gpc[0], CFI_attribute_other, + CFI_type_double , gpc_nbytes, 1, gpc_extent) + + CFI_establish(icoeff_ptr, &icoeff[0], CFI_attribute_other, + CFI_type_double , icoeff_nbytes, 1, icoeff_extent) + + c__pdafomi_get_interp_coeff_lin1d(gpc_ptr, &oc, icoeff_ptr) + + return icoeff_np + + +def get_interp_coeff_lin(int num_gp, int n_dim, double [::1,:] gpc, + double [::1] oc, double [::1] icoeff): + r"""get_interp_coeff_lin(num_gp: int, n_dim: int, gpc: np.ndarray, oc: np.ndarray, icoeff: np.ndarray) -> np.ndarray + + The coefficient for linear interpolation up to 3D. + + The resulting coefficient is used in :func:`pyPDAF.PDAFomi.obs_op_interp_lin`. + + See introduction in `relevant PDAF-OMI wiki page + `_ + + Parameters + ---------- + gpc : ndarray[tuple[num_gp, n_dim, ...], np.float64] + Coordinates of grid points + The order of the grid points in gcoords has to + be consistent with the order of the indices specified in + `id_obs_p` of `obs_f`. + The 1st-th dimension num_gp is Length of icoeff + The 2nd-th dimension n_dim is Number of dimensions in interpolation + oc : ndarray[tuple[n_dim, ...], np.float64] + Coordinates of observation + The array dimension `n_dim` is Number of dimensions in interpolation + icoeff : ndarray[tuple[num_gp, ...], np.float64] + Interpolation coefficients (num_gp) + The array dimension `num_gp` is Length of icoeff + + Returns + ------- + icoeff : ndarray[tuple[num_gp, ...], np.float64] + Interpolation coefficients (num_gp) + + The array dimension `num_gp` is Length of icoeff + """ + cdef CFI_cdesc_rank1 icoeff_cfi + cdef CFI_cdesc_t *icoeff_ptr = &icoeff_cfi + cdef size_t icoeff_nbytes = icoeff.nbytes + cdef CFI_index_t icoeff_extent[1] + icoeff_extent[0] = icoeff.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] icoeff_np = np.asarray(icoeff, dtype=np.float64, order="F") + cdef CFI_cdesc_rank2 gpc_cfi + cdef CFI_cdesc_t *gpc_ptr = &gpc_cfi + cdef size_t gpc_nbytes = gpc.nbytes + cdef CFI_index_t gpc_extent[2] + gpc_extent[0] = gpc.shape[0] + gpc_extent[1] = gpc.shape[1] + cdef CFI_cdesc_rank1 oc_cfi + cdef CFI_cdesc_t *oc_ptr = &oc_cfi + cdef size_t oc_nbytes = oc.nbytes + cdef CFI_index_t oc_extent[1] + oc_extent[0] = oc.shape[0] + with nogil: + CFI_establish(gpc_ptr, &gpc[0,0], CFI_attribute_other, + CFI_type_double , gpc_nbytes, 2, gpc_extent) + + CFI_establish(oc_ptr, &oc[0], CFI_attribute_other, + CFI_type_double , oc_nbytes, 1, oc_extent) + + CFI_establish(icoeff_ptr, &icoeff[0], CFI_attribute_other, + CFI_type_double , icoeff_nbytes, 1, icoeff_extent) + + c__pdafomi_get_interp_coeff_lin(&num_gp, &n_dim, gpc_ptr, oc_ptr, + icoeff_ptr) + + return icoeff_np + + +def init_dim_obs_l_iso(int i_obs, double [::1] coords_l, int locweight, + double cradius, double sradius, int cnt_obs_l_all): + r"""init_dim_obs_l_iso(i_obs: int, coords_l: np.ndarray, locweight: int, cradius: float, sradius: float, cnt_obs_l_all: int) -> int + + Initialize the observation information corresponding to an isotropic local analysis domain. + + One can set localization parameters, like the localization radius, for each observation type. + + The function has to be called in user-supplied function of + `init_dim_obs_l_OBTYPE` in each observation module if a + domain-localized filter (LESTKF/LETKF/LNETF/LSEIK)is used. + + It initialises the local observation information for PDAF-OMI for a + single local analysis domain. This is used for isotropic localisation + where the localisation radius is the same in all directions. + + See also `relevant PDAF wiki page `_ + + Parameters + ---------- + i_obs : int + index of observation type + coords_l : ndarray[tuple[ncoord, ...], np.float64] + Coordinates of current analysis domain + The array dimension `ncoord` is number of coordinate dimension + locweight : int + Types of localization function + 0) unit weight; 1) exponential; 2) 5-th order polynomial; + 3) 5-th order polynomial with regulatioin using mean variance; + 4) 5-th order polynomial with regulatioin using variance of single observation point; + cradius : float + Vector of localization cut-off radii; observation weight=0 if distance > cradius + sradius : float + Vector of support radii of localization function. + It has no impact if locweight=0; weight = exp(-d / sradius) if locweight=1; + weight = 0 if d >= sradius else f(sradius, distance) if locweight in [2,3,4]. + cnt_obs_l_all : int + Local dimension of current observation vector + + Returns + ------- + cnt_obs_l_all : int + Local dimension of current observation vector + """ + cdef CFI_cdesc_rank1 coords_l_cfi + cdef CFI_cdesc_t *coords_l_ptr = &coords_l_cfi + cdef size_t coords_l_nbytes = coords_l.nbytes + cdef CFI_index_t coords_l_extent[1] + coords_l_extent[0] = coords_l.shape[0] + with nogil: + CFI_establish(coords_l_ptr, &coords_l[0], CFI_attribute_other, + CFI_type_double , coords_l_nbytes, 1, coords_l_extent) + + c__pdafomi_init_dim_obs_l_iso(&i_obs, coords_l_ptr, &locweight, + &cradius, &sradius, &cnt_obs_l_all) + + return cnt_obs_l_all + + +def init_dim_obs_l_noniso(int i_obs, double [::1] coords_l, + int locweight, double [::1] cradius, double [::1] sradius, + int cnt_obs_l_all): + r"""init_dim_obs_l_noniso(i_obs: int, coords_l: np.ndarray, locweight: int, cradius: np.ndarray, sradius: np.ndarray, cnt_obs_l_all: int) -> int + + Initialize the observation information corresponding to a non-isotropic local analysis domain. + + One can set localization parameters, like the localization radius, for each observation type. + + Here, each dimension can use a different localisation radius. + + The function has to be called in user-supplied function of + `init_dim_obs_l_OBTYPE` in each observation module if a + domain-localized filter (LESTKF/LETKF/LNETF/LSEIK)is used. + + It initialises the local observation information for PDAF-OMI for a + single local analysis domain. This is used for isotropic localisation + where the localisation radius is the same in all directions. + + See also `relevant PDAF wiki page `_ + as well as `non-isotropic localisation page `_ + + Parameters + ---------- + i_obs : int + index of observation type + coords_l : ndarray[tuple[ncoord, ...], np.float64] + Coordinates of current analysis domain + The array dimension `ncoord` is number of coordinate dimension + locweight : int + Types of localization function + 0) unit weight; 1) exponential; 2) 5-th order polynomial; + 3) 5-th order polynomial with regulatioin using mean variance; + 4) 5-th order polynomial with regulatioin using variance of single observation point; + cradius : ndarray[tuple[ncoord, ...], np.float64] + Vector of localization cut-off radii; observation weight=0 if distance > cradius + The array dimension `ncoord` is number of coordinate dimension + sradius : ndarray[tuple[ncoord, ...], np.float64] + Vector of support radii of localization function. + It has no impact if locweight=0; weight = exp(-d / sradius) if locweight=1; + weight = 0 if d >= sradius else f(sradius, distance) if locweight in [2,3,4]. + The array dimension `ncoord` is number of coordinate dimension + cnt_obs_l_all : int + Local dimension of current observation vector + + Returns + ------- + cnt_obs_l_all : int + Local dimension of current observation vector + """ + cdef CFI_cdesc_rank1 coords_l_cfi + cdef CFI_cdesc_t *coords_l_ptr = &coords_l_cfi + cdef size_t coords_l_nbytes = coords_l.nbytes + cdef CFI_index_t coords_l_extent[1] + coords_l_extent[0] = coords_l.shape[0] + cdef CFI_cdesc_rank1 cradius_cfi + cdef CFI_cdesc_t *cradius_ptr = &cradius_cfi + cdef size_t cradius_nbytes = cradius.nbytes + cdef CFI_index_t cradius_extent[1] + cradius_extent[0] = cradius.shape[0] + cdef CFI_cdesc_rank1 sradius_cfi + cdef CFI_cdesc_t *sradius_ptr = &sradius_cfi + cdef size_t sradius_nbytes = sradius.nbytes + cdef CFI_index_t sradius_extent[1] + sradius_extent[0] = sradius.shape[0] + with nogil: + CFI_establish(coords_l_ptr, &coords_l[0], CFI_attribute_other, + CFI_type_double , coords_l_nbytes, 1, coords_l_extent) + + CFI_establish(cradius_ptr, &cradius[0], CFI_attribute_other, + CFI_type_double , cradius_nbytes, 1, cradius_extent) + + CFI_establish(sradius_ptr, &sradius[0], CFI_attribute_other, + CFI_type_double , sradius_nbytes, 1, sradius_extent) + + c__pdafomi_init_dim_obs_l_noniso(&i_obs, coords_l_ptr, &locweight, + cradius_ptr, sradius_ptr, + &cnt_obs_l_all) + + return cnt_obs_l_all + + +def init_dim_obs_l_noniso_locweights(int i_obs, double [::1] coords_l, + int [::1] locweights, double [::1] cradius, double [::1] sradius, + int cnt_obs_l): + r"""init_dim_obs_l_noniso_locweights(i_obs: int, coords_l: np.ndarray, locweights: np.ndarray, cradius: np.ndarray, sradius: np.ndarray, cnt_obs_l: int) -> int + + Initialize the observation information corresponding to a non-isotropic local analysis domain. + + One can set localization parameters, like the localization radius, for each observation type. + + Here, each dimension can use a different localisation radius and a different + localisation weight. + + The function has to be called in user-supplied function of + `init_dim_obs_l_OBTYPE` in each observation module if a + domain-localized filter (LESTKF/LETKF/LNETF/LSEIK)is used. + + It initialises the local observation information for PDAF-OMI for a + single local analysis domain. This is used for isotropic localisation + where the localisation radius is the same in all directions. + + See also `relevant PDAF wiki page `_ + as well as `non-isotropic localisation page `_ + + Parameters + ---------- + i_obs : int + index of observation type + coords_l : ndarray[tuple[ncoord, ...], np.float64] + Coordinates of current analysis domain + The array dimension `ncoord` is number of coordinate dimension + locweights : ndarray[tuple[2, ...], np.intc] + Types of localization function + 0) unit weight; 1) exponential; 2) 5-th order polynomial; + 3) 5-th order polynomial with regulatioin using mean variance; + 4) 5-th order polynomial with regulatioin using variance of single observation point; + The first dimension is horizontal weight function and the second is the vertical function + cradius : ndarray[tuple[ncoord, ...], np.float64] + Vector of localization cut-off radii for each dimension; observation weight=0 if distance > cradius + The array dimension `ncoord` is number of coordinate dimension + sradius : ndarray[tuple[ncoord, ...], np.float64] + Vector of support radii of localization function for each dimension. + It has no impact if locweight=0; weight = exp(-d / sradius) if locweight=1; + weight = 0 if d >= sradius else f(sradius, distance) if locweight in [2,3,4]. + The array dimension `ncoord` is number of coordinate dimension + cnt_obs_l : int + Local dimension of current observation vector + + Returns + ------- + cnt_obs_l : int + Local dimension of current observation vector + """ + cdef CFI_cdesc_rank1 coords_l_cfi + cdef CFI_cdesc_t *coords_l_ptr = &coords_l_cfi + cdef size_t coords_l_nbytes = coords_l.nbytes + cdef CFI_index_t coords_l_extent[1] + coords_l_extent[0] = coords_l.shape[0] + cdef CFI_cdesc_rank1 locweights_cfi + cdef CFI_cdesc_t *locweights_ptr = &locweights_cfi + cdef size_t locweights_nbytes = locweights.nbytes + cdef CFI_index_t locweights_extent[1] + locweights_extent[0] = locweights.shape[0] + cdef CFI_cdesc_rank1 cradius_cfi + cdef CFI_cdesc_t *cradius_ptr = &cradius_cfi + cdef size_t cradius_nbytes = cradius.nbytes + cdef CFI_index_t cradius_extent[1] + cradius_extent[0] = cradius.shape[0] + cdef CFI_cdesc_rank1 sradius_cfi + cdef CFI_cdesc_t *sradius_ptr = &sradius_cfi + cdef size_t sradius_nbytes = sradius.nbytes + cdef CFI_index_t sradius_extent[1] + sradius_extent[0] = sradius.shape[0] + with nogil: + CFI_establish(coords_l_ptr, &coords_l[0], CFI_attribute_other, + CFI_type_double , coords_l_nbytes, 1, coords_l_extent) + + CFI_establish(locweights_ptr, &locweights[0], CFI_attribute_other, + CFI_type_int , locweights_nbytes, 1, locweights_extent) + + CFI_establish(cradius_ptr, &cradius[0], CFI_attribute_other, + CFI_type_double , cradius_nbytes, 1, cradius_extent) + + CFI_establish(sradius_ptr, &sradius[0], CFI_attribute_other, + CFI_type_double , sradius_nbytes, 1, sradius_extent) + + c__pdafomi_init_dim_obs_l_noniso_locweights(&i_obs, coords_l_ptr, + locweights_ptr, + cradius_ptr, + sradius_ptr, &cnt_obs_l) + + return cnt_obs_l + + +def obs_op_gridpoint(int i_obs, double [::1] state_p, double [::1] obs_f_all): + r"""obs_op_gridpoint(i_obs: int, state_p: np.ndarray, obs_f_all: np.ndarray) -> np.ndarray + + A (partial) identity observation operator + + This observation operator is used + when observations and model use the same grid. + + The observations operator selects state vectors + where observations are present based on properties given + in `obs_f`, e.g., `id_obs_p`. + + The function is used in + the user-supplied function :func:`py__obs_op_pdaf`. + + Parameters + ---------- + i_obs : int + index of observations + state_p : ndarray[tuple[dim_p, ...], np.float64] + PE-local model state (dim_p) + The array dimension `dim_p` is dimension of model state + obs_f_all : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed state for all observation types (nobs_f_all) + The array dimension `nobs_f_all` is dimension of the observation + + Returns + ------- + obs_f_all : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed state for all observation types (nobs_f_all) + + The array dimension `nobs_f_all` is dimension of the observation + """ + cdef CFI_cdesc_rank1 obs_f_all_cfi + cdef CFI_cdesc_t *obs_f_all_ptr = &obs_f_all_cfi + cdef size_t obs_f_all_nbytes = obs_f_all.nbytes + cdef CFI_index_t obs_f_all_extent[1] + obs_f_all_extent[0] = obs_f_all.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obs_f_all_np = np.asarray(obs_f_all, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 state_p_cfi + cdef CFI_cdesc_t *state_p_ptr = &state_p_cfi + cdef size_t state_p_nbytes = state_p.nbytes + cdef CFI_index_t state_p_extent[1] + state_p_extent[0] = state_p.shape[0] + with nogil: + CFI_establish(state_p_ptr, &state_p[0], CFI_attribute_other, + CFI_type_double , state_p_nbytes, 1, state_p_extent) + + CFI_establish(obs_f_all_ptr, &obs_f_all[0], CFI_attribute_other, + CFI_type_double , obs_f_all_nbytes, 1, obs_f_all_extent) + + c__pdafomi_obs_op_gridpoint(&i_obs, state_p_ptr, obs_f_all_ptr) + + return obs_f_all_np + + +def obs_op_gridavg(int i_obs, int nrows, double [::1] state_p, + double [::1] obs_f_all): + r"""obs_op_gridavg(i_obs: int, nrows: int, state_p: np.ndarray, obs_f_all: np.ndarray) -> np.ndarray + + Observation operator that average values on given model grid points. + + The averaged model grid points are specified in `id_obs_p` property of `obs_f`, + which can be set in :func:`pyPDAF.PDAF.omi_set_id_obs_p`. + + The function is used in the user-supplied function `py__obs_op_pdaf`. + + Parameters + ---------- + i_obs : int + index of observations + nrows : int + Number of values to be averaged + state_p : ndarray[tuple[dim_p, ...], np.float64] + PE-local model state (dim_p) + The array dimension `dim_p` is dimension of model state + obs_f_all : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed state for all observation types (nobs_f_all) + The array dimension `nobs_f_all` is dimension of the observation + + Returns + ------- + obs_f_all : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed state for all observation types (nobs_f_all) + + The array dimension `nobs_f_all` is dimension of the observation + """ + cdef CFI_cdesc_rank1 obs_f_all_cfi + cdef CFI_cdesc_t *obs_f_all_ptr = &obs_f_all_cfi + cdef size_t obs_f_all_nbytes = obs_f_all.nbytes + cdef CFI_index_t obs_f_all_extent[1] + obs_f_all_extent[0] = obs_f_all.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obs_f_all_np = np.asarray(obs_f_all, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 state_p_cfi + cdef CFI_cdesc_t *state_p_ptr = &state_p_cfi + cdef size_t state_p_nbytes = state_p.nbytes + cdef CFI_index_t state_p_extent[1] + state_p_extent[0] = state_p.shape[0] + with nogil: + CFI_establish(state_p_ptr, &state_p[0], CFI_attribute_other, + CFI_type_double , state_p_nbytes, 1, state_p_extent) + + CFI_establish(obs_f_all_ptr, &obs_f_all[0], CFI_attribute_other, + CFI_type_double , obs_f_all_nbytes, 1, obs_f_all_extent) + + c__pdafomi_obs_op_gridavg(&i_obs, &nrows, state_p_ptr, obs_f_all_ptr) + + return obs_f_all_np + +def obs_op_extern(int i_obs, double [::1] ostate_p, + double [::1] obs_f_all): + """obs_op_extern(i_obs: int, ostate_p: np.ndarray, obs_f_all: np.ndarray) -> np.ndarray + + Observation operator for given observed model state. + + Application of observation operator for the case that + a user performs the actual observation operator elsewhere, + e.g., directly in the model during the forecast or offline. + For this case, the user can provide the observed model state + to this routine and it will just call :func:`pyPDAF.PDAFomi.gather_obsstate`, + to obtain the full observed vector `obs_f_all`. + + This has to be called in all filter processes. + + Parameters + ---------- + i_obs : int + index into observation arrays + ostate_p : ndarray[np.float64, ndim=1] + PE-local observed model state + Array shape: (:) + obs_f_all : ndarray[np.float64, ndim=1] + Full observed model state for all observation types + Array shape: (:) + + Returns + ------- + obs_f_all : ndarray[np.float64, ndim=1] + Full observed state for all observation types + Array shape: (:) + """ + cdef CFI_cdesc_rank1 obs_f_all_cfi + cdef CFI_cdesc_t *obs_f_all_ptr = &obs_f_all_cfi + cdef size_t obs_f_all_nbytes = obs_f_all.nbytes + cdef CFI_index_t obs_f_all_extent[1] + obs_f_all_extent[0] = obs_f_all.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obs_f_all_np = np.asarray(obs_f_all, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 ostate_p_cfi + cdef CFI_cdesc_t *ostate_p_ptr = &ostate_p_cfi + cdef size_t ostate_p_nbytes = ostate_p.nbytes + cdef CFI_index_t ostate_p_extent[1] + ostate_p_extent[0] = ostate_p.shape[0] + with nogil: + CFI_establish(ostate_p_ptr, &ostate_p[0], CFI_attribute_other, + CFI_type_double , ostate_p_nbytes, 1, ostate_p_extent) + + CFI_establish(obs_f_all_ptr, &obs_f_all[0], CFI_attribute_other, + CFI_type_double , obs_f_all_nbytes, 1, obs_f_all_extent) + + c__pdafomi_obs_op_extern(&i_obs, ostate_p_ptr, obs_f_all_ptr) + + return obs_f_all_np + + +def obs_op_interp_lin(int i_obs, int nrows, double [::1] state_p, + double [::1] obs_f_all): + r"""obs_op_interp_lin(i_obs: int, nrows: int, state_p: np.ndarray, obs_f_all: np.ndarray) -> np.ndarray + + Observation operator that linearly interpolates model grid values to observation location. + + The grid points used by linear interpolation is specified in `id_obs_p` of `obs_f`, + which can be set by :func:`pyPDAF.PDAFomi.set_id_obs_p`. + + The function also requires `icoeff_p` attribute of `obs_f`, + which can be set by :func:`pyPDAF.PDAFomi.set_icoeff_p` + + The interpolation coefficient can be obtained by :func:`pyPDAF.PDAFomi.get_interp_coeff_lin1D`, + :func:`pyPDAF.PDAFomi.get_interp_coeff_lin`, and + :func:`pyPDAF.PDAFomi.get_interp_coeff_tri` + + The details of interpolation setup can be found at + `relevant PDAF wiki page `_ + + The function is used in the user-supplied function `py__obs_op_pdaf`. + + Parameters + ---------- + i_obs : int + index of observations + nrows : int + Number of values to be averaged + state_p : ndarray[tuple[dim_p, ...], np.float64] + PE-local model state (dim_p) + The array dimension `dim_p` is dimension of model state + obs_f_all : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed state for all observation types (nobs_f_all) + The array dimension `nobs_f_all` is dimension of the observation + + Returns + ------- + obs_f_all : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed state for all observation types (nobs_f_all) + + The array dimension `nobs_f_all` is dimension of the observation + """ + cdef CFI_cdesc_rank1 obs_f_all_cfi + cdef CFI_cdesc_t *obs_f_all_ptr = &obs_f_all_cfi + cdef size_t obs_f_all_nbytes = obs_f_all.nbytes + cdef CFI_index_t obs_f_all_extent[1] + obs_f_all_extent[0] = obs_f_all.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obs_f_all_np = np.asarray(obs_f_all, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 state_p_cfi + cdef CFI_cdesc_t *state_p_ptr = &state_p_cfi + cdef size_t state_p_nbytes = state_p.nbytes + cdef CFI_index_t state_p_extent[1] + state_p_extent[0] = state_p.shape[0] + with nogil: + CFI_establish(state_p_ptr, &state_p[0], CFI_attribute_other, + CFI_type_double , state_p_nbytes, 1, state_p_extent) + + CFI_establish(obs_f_all_ptr, &obs_f_all[0], CFI_attribute_other, + CFI_type_double , obs_f_all_nbytes, 1, obs_f_all_extent) + + c__pdafomi_obs_op_interp_lin(&i_obs, &nrows, state_p_ptr, obs_f_all_ptr) + + return obs_f_all_np + + +def obs_op_adj_gridpoint(int i_obs, double [::1] obs_f_all, + double [::1] state_p): + r"""obs_op_adj_gridpoint(i_obs: int, obs_f_all: np.ndarray, state_p: np.ndarray) -> np.ndarray + + The adjoint observation operator of :func:`pyPDAF.PDAFomi.obs_op_gridpoint`. + + This function performs :math:`\mathbf{H}^\mathrm{T}\mathbf{y}`, + where :math:`\mathbf{H}` is the observation operator and + :math:`\mathbf{y}` is any state in observation space. + + Here :math:`\mathbf{H}` is :func:`pyPDAF.PDAFomi.obs_op_gridpoint`. + + Parameters + ---------- + i_obs : int + index of observations + obs_f_all : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed state for all observation types (nobs_f_all) + The array dimension `nobs_f_all` is dimension of the observation + state_p : ndarray[tuple[dim_p, ...], np.float64] + PE-local model state (dim_p) + The array dimension `dim_p` is dimension of model state + + Returns + ------- + state_p : ndarray[tuple[dim_p, ...], np.float64] + :math:`\mathbf{H}^\mathrm{T}\mathbf{y}` + PE-local model state (dim_p) + The array dimension `dim_p` is dimension of model state + """ + cdef CFI_cdesc_rank1 state_p_cfi + cdef CFI_cdesc_t *state_p_ptr = &state_p_cfi + cdef size_t state_p_nbytes = state_p.nbytes + cdef CFI_index_t state_p_extent[1] + state_p_extent[0] = state_p.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 obs_f_all_cfi + cdef CFI_cdesc_t *obs_f_all_ptr = &obs_f_all_cfi + cdef size_t obs_f_all_nbytes = obs_f_all.nbytes + cdef CFI_index_t obs_f_all_extent[1] + obs_f_all_extent[0] = obs_f_all.shape[0] + with nogil: + CFI_establish(obs_f_all_ptr, &obs_f_all[0], CFI_attribute_other, + CFI_type_double , obs_f_all_nbytes, 1, obs_f_all_extent) + + CFI_establish(state_p_ptr, &state_p[0], CFI_attribute_other, + CFI_type_double , state_p_nbytes, 1, state_p_extent) + + c__pdafomi_obs_op_adj_gridpoint(&i_obs, obs_f_all_ptr, state_p_ptr) + + return state_p_np + + +def obs_op_adj_gridavg(int i_obs, int nrows, double [::1] obs_f_all, + double [::1] state_p): + r"""obs_op_adj_gridavg(i_obs: int, nrows: int, obs_f_all: np.ndarray, state_p: np.ndarray) -> np.ndarray + + The adjoint observation operator of :func:`pyPDAF.PDAFomi.obs_op_gridavg`. + + This function performs :math:`\mathbf{H}^\mathrm{T}\mathbf{y}`, + where :math:`\mathbf{H}` is the observation operator and + :math:`\mathbf{y}` is any state in observation space. + + Here :math:`\mathbf{H}` is :func:`pyPDAF.PDAFomi.obs_op_gridavg`. + + Parameters + ---------- + i_obs : int + index of observations + nrows : int + Number of values to be averaged + obs_f_all : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed state for all observation types (nobs_f_all) + The array dimension `nobs_f_all` is dimension of the observation + state_p : ndarray[tuple[dim_p, ...], np.float64] + PE-local model state (dim_p) + The array dimension `dim_p` is dimension of model state + + Returns + ------- + state_p : ndarray[tuple[dim_p, ...], np.float64] + :math:`\mathbf{H}^\mathrm{T}\mathbf{y}` + PE-local model state (dim_p) + The array dimension `dim_p` is dimension of model state + """ + cdef CFI_cdesc_rank1 state_p_cfi + cdef CFI_cdesc_t *state_p_ptr = &state_p_cfi + cdef size_t state_p_nbytes = state_p.nbytes + cdef CFI_index_t state_p_extent[1] + state_p_extent[0] = state_p.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 obs_f_all_cfi + cdef CFI_cdesc_t *obs_f_all_ptr = &obs_f_all_cfi + cdef size_t obs_f_all_nbytes = obs_f_all.nbytes + cdef CFI_index_t obs_f_all_extent[1] + obs_f_all_extent[0] = obs_f_all.shape[0] + with nogil: + CFI_establish(obs_f_all_ptr, &obs_f_all[0], CFI_attribute_other, + CFI_type_double , obs_f_all_nbytes, 1, obs_f_all_extent) + + CFI_establish(state_p_ptr, &state_p[0], CFI_attribute_other, + CFI_type_double , state_p_nbytes, 1, state_p_extent) + + c__pdafomi_obs_op_adj_gridavg(&i_obs, &nrows, obs_f_all_ptr, + state_p_ptr) + + return state_p_np + + +def obs_op_adj_interp_lin(int i_obs, int nrows, double [::1] obs_f_all, + double [::1] state_p): + r"""obs_op_adj_interp_lin(i_obs: int, nrows: int, obs_f_all: np.ndarray, state_p: np.ndarray) -> np.ndarray + + The adjoint observation operator of :func:`pyPDAF.PDAFomi.obs_op_interp_lin`. + + This function performs :math:`\mathbf{H}^\mathrm{T}\mathbf{y}`, + where :math:`\mathbf{H}` is the observation operator and + :math:`\mathbf{y}` is any state in observation space. + + Here :math:`\mathbf{H}` is :func:`pyPDAF.PDAFomi.obs_op_interp_lin`. + + Parameters + ---------- + i_obs : int + index of observations + nrows : int + Number of values to be averaged + obs_f_all : ndarray[tuple[nobs_f_all, ...], np.float64] + Full observed state for all observation types (nobs_f_all) + The array dimension `nobs_f_all` is dimension of the observation + state_p : ndarray[tuple[dim_p, ...], np.float64] + PE-local model state (dim_p) + The array dimension `dim_p` is dimension of model state + + Returns + ------- + state_p : ndarray[tuple[dim_p, ...], np.float64] + :math:`\mathbf{H}^\mathrm{T}\mathbf{y}` + PE-local model state (dim_p) + The array dimension `dim_p` is dimension of model state + """ + cdef CFI_cdesc_rank1 state_p_cfi + cdef CFI_cdesc_t *state_p_ptr = &state_p_cfi + cdef size_t state_p_nbytes = state_p.nbytes + cdef CFI_index_t state_p_extent[1] + state_p_extent[0] = state_p.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] state_p_np = np.asarray(state_p, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 obs_f_all_cfi + cdef CFI_cdesc_t *obs_f_all_ptr = &obs_f_all_cfi + cdef size_t obs_f_all_nbytes = obs_f_all.nbytes + cdef CFI_index_t obs_f_all_extent[1] + obs_f_all_extent[0] = obs_f_all.shape[0] + with nogil: + CFI_establish(obs_f_all_ptr, &obs_f_all[0], CFI_attribute_other, + CFI_type_double , obs_f_all_nbytes, 1, obs_f_all_extent) + + CFI_establish(state_p_ptr, &state_p[0], CFI_attribute_other, + CFI_type_double , state_p_nbytes, 1, state_p_extent) + + c__pdafomi_obs_op_adj_interp_lin(&i_obs, &nrows, obs_f_all_ptr, + state_p_ptr) + + return state_p_np + + +def observation_localization_weights(int i_obs, int ncols, + double [::1,:] a_l, int dim_obs_l, int verbose): + r"""observation_localization_weights(i_obs: int, ncols: int, a_l: np.ndarray, dim_obs_l: int, verbose: int) -> np.ndarray + + Returns a vector of observation localisation weights. + + The weights are based on specifications given by localisation setups and + observation coordinates in OMI. This function is used in the case of + non-diagonal observation error covariance matrix where one has to perform + localisation in user-supplied functions, e.g., + :func:`pyPDAF.c__prodrinva_pdaf` or :func:`pyPDAF.c__likelihood_l_pdaf`. + + Here, `a_l` is typically the input array in :func:`pyPDAF.c__prodrinva_pdaf`. + + Parameters + ---------- + i_obs : int + index into observation arrays + ncols : int + Rank of initial covariance matrix + a_l : ndarray[np.float64, ndim=2] + Input matrix (thisobs_l%dim_obs_l, ncols) + Array shape: (:, :) + dim_obs_l : int + Dimension of local observation vector of the i_obs-th observation type + verbose : int + Verbosity flag + + Returns + ------- + weight : ndarray[np.float64, ndim=1] + > Localization weights + Array shape: (thisobs_l(i_obs)%dim_obs_l) + """ + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] weight_np = np.zeros((dim_obs_l), dtype=np.float64, order="F") + cdef double [::1] weight = weight_np + cdef CFI_cdesc_rank2 a_l_cfi + cdef CFI_cdesc_t *a_l_ptr = &a_l_cfi + cdef size_t a_l_nbytes = a_l.nbytes + cdef CFI_index_t a_l_extent[2] + a_l_extent[0] = a_l.shape[0] + a_l_extent[1] = a_l.shape[1] + with nogil: + CFI_establish(a_l_ptr, &a_l[0,0], CFI_attribute_other, + CFI_type_double , a_l_nbytes, 2, a_l_extent) + + c__pdafomi_observation_localization_weights(&i_obs, &ncols, + a_l_ptr, &weight[0], + &verbose) + + return weight_np + + +def set_debug_flag(int debugval): + """set_debug_flag(debugval: int) -> None + + Activate the debug output of the PDAFomi. + + Starting from the use of this function, + the debug infomation is sent to screen output. + The screen output end when the debug flag is + set to 0 by this function. + + See also `relevant PDAF wiki page `_ + + Parameters + ---------- + debugval : int + Value for debugging flag + """ + with nogil: + c__pdafomi_set_debug_flag(&debugval) + + + +def set_dim_obs_l(int i_obs, int cnt_obs_l_all, int cnt_obs_l): + """set_dim_obs_l(i_obs: int, cnt_obs_l_all: int, cnt_obs_l: int) -> Tuple[int, int] + + Stores the local number of observations for OMI-internal initialisations. + + This is used for alternative to :func:`pyPDF.PDAFomi.init_dim_obs_l`. + + See more details in `relevant PDAF wiki page `_ + + Parameters + ---------- + i_obs : int + index into observation arrays + cnt_obs_l_all : int + Local dimension of observation vector over all obs. types + cnt_obs_l : int + Local dimension of single observation type vector + + Returns + ------- + cnt_obs_l_all : int + Local dimension of observation vector over all obs. types + cnt_obs_l : int + Local dimension of single observation type vector + """ + with nogil: + c__pdafomi_set_dim_obs_l(&i_obs, &cnt_obs_l_all, &cnt_obs_l) + + return cnt_obs_l_all, cnt_obs_l + + +def set_localization(int i_obs, double cradius, double sradius, + int locweight): + r"""set_localization(i_obs: int, cradius: float, sradius: float, locweight: int) -> None + + Stores the isotropic localization parameters (cradius, sradius, locweight) in OMI. + + This is used for alternative to :func:`pyPDF.PDAFomi.init_dim_obs_l`. + + See more details in `relevant PDAF wiki page `_ + + + Parameters + ---------- + i_obs : int + index into observation arrays + cradius : double + Localization cut-off radius + sradius : double + Support radius of localization function + locweight : int + Type of localization function + """ + with nogil: + c__pdafomi_set_localization(&i_obs, &cradius, &sradius, &locweight) + + + +def set_localization_noniso(int i_obs, int nradii, double [::1] cradius, + double [::1] sradius, int locweight, int locweight_v): + r"""set_localization_noniso(i_obs: int, nradii: int, cradius: np.ndarray, sradius: np.ndarray, locweight: int, locweight_v: int) -> None + + Stores the non-isotropic localization parameters (cradius, sradius, locweight) in OMI. + + This is used for alternative to :func:`pyPDF.PDAFomi.init_dim_obs_l`. + + See more details in `relevant PDAF wiki page `_ + + + + Parameters + ---------- + i_obs : int + index into observation arrays + nradii : int + Number of radii to consider for localization + cradius : ndarray[np.float64, ndim=1] + Localization cut-off radius + Array shape: (nradii) + sradius : ndarray[np.float64, ndim=1] + Support radius of localization function + Array shape: (nradii) + locweight : int + Type of localization function + locweight_v : int + Type of localization function in vertical direction (only for nradii=3) + + Returns + ------- + """ + with nogil: + c__pdafomi_set_localization_noniso(&i_obs, &nradii, &cradius[0], + &sradius[0], &locweight, + &locweight_v) + + + +def set_localize_covar_iso(int i_obs, int dim, int ncoords, + double [::1,:] coords, int locweight, double cradius, double sradius): + r"""set_localize_covar_iso(i_obs: int, dim: int, ncoords: int, coords: np.ndarray, locweight: int, cradius: float, sradius: float) -> None + + Initialise local observation information for isotropic covariance localisation. + + This is used in stochastic EnKF/EAKF/EnSRF. This is called in user-supplied functions + :func:`pyPDAF.c__init_dim_obs_pdaf`. + + Parameters + ---------- + i_obs : int + index into observation arrays + dim : int + State dimension + ncoords : int + number of coordinate directions + coords : ndarray[np.float64, ndim=2] + Coordinates of state vector elements + Array shape: (:,:) + locweight : int + Localization weight type + cradius : double + localization radius + sradius : double + support radius for weight functions + """ + cdef CFI_cdesc_rank2 coords_cfi + cdef CFI_cdesc_t *coords_ptr = &coords_cfi + cdef size_t coords_nbytes = coords.nbytes + cdef CFI_index_t coords_extent[2] + coords_extent[0] = coords.shape[0] + coords_extent[1] = coords.shape[1] + with nogil: + CFI_establish(coords_ptr, &coords[0,0], CFI_attribute_other, + CFI_type_double , coords_nbytes, 2, coords_extent) + + c__pdafomi_set_localize_covar_iso(&i_obs, &dim, &ncoords, + coords_ptr, &locweight, &cradius, + &sradius) + + + +def set_localize_covar_noniso(int i_obs, int dim, int ncoords, + double [::1,:] coords, int locweight, double [::1] cradius, + double [::1] sradius): + r"""set_localize_covar_noniso(i_obs: int, dim: int, ncoords: int, coords: np.ndarray, locweight: int, cradius: np.ndarray, sradius: np.ndarray) -> None + + Initialise local observation information for non-isotropic covariance localisation. + + This is used in stochastic EnKF/EAKF/EnSRF. This is called in user-supplied functions + :func:`pyPDAF.c__init_dim_obs_pdaf`. + + Here, localisation radii differ for each spatial dimension. + + Parameters + ---------- + i_obs : int + index into observation arrays + dim : int + State dimension + ncoords : int + number of coordinate directions + coords : ndarray[np.float64, ndim=2] + Coordinates of state vector elements + Array shape: (:,:) + locweight : int + Localization weight type + cradius : ndarray[np.float64, ndim=1] + Vector of localization cut-off radii + Array shape: (:) + sradius : ndarray[np.float64, ndim=1] + Vector of support radii of localization function + Array shape: (:) + """ + cdef CFI_cdesc_rank2 coords_cfi + cdef CFI_cdesc_t *coords_ptr = &coords_cfi + cdef size_t coords_nbytes = coords.nbytes + cdef CFI_index_t coords_extent[2] + coords_extent[0] = coords.shape[0] + coords_extent[1] = coords.shape[1] + cdef CFI_cdesc_rank1 cradius_cfi + cdef CFI_cdesc_t *cradius_ptr = &cradius_cfi + cdef size_t cradius_nbytes = cradius.nbytes + cdef CFI_index_t cradius_extent[1] + cradius_extent[0] = cradius.shape[0] + cdef CFI_cdesc_rank1 sradius_cfi + cdef CFI_cdesc_t *sradius_ptr = &sradius_cfi + cdef size_t sradius_nbytes = sradius.nbytes + cdef CFI_index_t sradius_extent[1] + sradius_extent[0] = sradius.shape[0] + with nogil: + CFI_establish(coords_ptr, &coords[0,0], CFI_attribute_other, + CFI_type_double , coords_nbytes, 2, coords_extent) + + CFI_establish(cradius_ptr, &cradius[0], CFI_attribute_other, + CFI_type_double , cradius_nbytes, 1, cradius_extent) + + CFI_establish(sradius_ptr, &sradius[0], CFI_attribute_other, + CFI_type_double , sradius_nbytes, 1, sradius_extent) + + c__pdafomi_set_localize_covar_noniso(&i_obs, &dim, &ncoords, + coords_ptr, &locweight, + cradius_ptr, sradius_ptr) + + + +def set_localize_covar_noniso_locweights(int i_obs, int dim, + int ncoords, double [::1,:] coords, int [::1] locweights, + double [::1] cradius, double [::1] sradius): + r"""set_localize_covar_noniso_locweights(i_obs: int, dim: int, ncoords: int, coords: np.ndarray, locweights: np.ndarray, cradius: np.ndarray, sradius: np.ndarray) -> None + + Initialise local observation information for non-isotropic covariance localisation. + + This is used in stochastic EnKF/EAKF/EnSRF. This is called in user-supplied functions + :func:`pyPDAF.c__init_dim_obs_pdaf`. + + Here, both weighting function and localisation radii differ for each spatial dimension. + + Parameters + ---------- + i_obs : int + index into observation arrays + dim : int + State dimension + ncoords : int + number of coordinate directions + coords : ndarray[np.float64, ndim=2] + Coordinates of state vector elements + Array shape: (:,:) + locweights : ndarray[np.intc, ndim=1] + Types of localization function + Array shape: (:) + cradius : ndarray[np.float64, ndim=1] + Vector of localization cut-off radii + Array shape: (:) + sradius : ndarray[np.float64, ndim=1] + Vector of support radii of localization function + Array shape: (:) + """ + cdef CFI_cdesc_rank2 coords_cfi + cdef CFI_cdesc_t *coords_ptr = &coords_cfi + cdef size_t coords_nbytes = coords.nbytes + cdef CFI_index_t coords_extent[2] + coords_extent[0] = coords.shape[0] + coords_extent[1] = coords.shape[1] + cdef CFI_cdesc_rank1 locweights_cfi + cdef CFI_cdesc_t *locweights_ptr = &locweights_cfi + cdef size_t locweights_nbytes = locweights.nbytes + cdef CFI_index_t locweights_extent[1] + locweights_extent[0] = locweights.shape[0] + cdef CFI_cdesc_rank1 cradius_cfi + cdef CFI_cdesc_t *cradius_ptr = &cradius_cfi + cdef size_t cradius_nbytes = cradius.nbytes + cdef CFI_index_t cradius_extent[1] + cradius_extent[0] = cradius.shape[0] + cdef CFI_cdesc_rank1 sradius_cfi + cdef CFI_cdesc_t *sradius_ptr = &sradius_cfi + cdef size_t sradius_nbytes = sradius.nbytes + cdef CFI_index_t sradius_extent[1] + sradius_extent[0] = sradius.shape[0] + with nogil: + CFI_establish(coords_ptr, &coords[0,0], CFI_attribute_other, + CFI_type_double , coords_nbytes, 2, coords_extent) + + CFI_establish(locweights_ptr, &locweights[0], CFI_attribute_other, + CFI_type_int , locweights_nbytes, 1, locweights_extent) + + CFI_establish(cradius_ptr, &cradius[0], CFI_attribute_other, + CFI_type_double , cradius_nbytes, 1, cradius_extent) + + CFI_establish(sradius_ptr, &sradius[0], CFI_attribute_other, + CFI_type_double , sradius_nbytes, 1, sradius_extent) + + c__pdafomi_set_localize_covar_noniso_locweights(&i_obs, &dim, + &ncoords, + coords_ptr, + locweights_ptr, + cradius_ptr, + sradius_ptr) + + + +def set_obs_diag(int diag): + """set_obs_diag(diag: int) -> None + + Activate or deactivate the observation diagnostics. + + By default, observation diagnostics are activated that stores + additional information for diagnostics. + However, as this functionality increases the required memory, + it might be desirable to deactivate this functionality. + + This function is used deactivate the observation diagnostics. + Once deactivated, one cannot use diagnostics in :mod:`pyPDAF.PDAFomi.diag`. + It is also possible to re-activate the observation diagnostics at a later time. + + The function can be called by all processes, but it is sufficient to call it + for those processes that handle observations, which usually are the filter processes. + + This function can be called after the initialization of PDAF in `pyPDAF.PDAF.init`. + + + Parameters + ---------- + diag : int + Value for observation diagnostics mode + - > 0: activates observation diagnostics + - 0: deactivates observation diagnostics + """ + with nogil: + c__pdafomi_set_obs_diag(&diag) + + + +def set_domain_limits(double [::1,:] lim_coords): + r"""set_domain_limits(lim_coords: np.ndarray) -> None + + Set the domain limits for domain decomposed local domain. + + This is for the use of :func:`pyPDAF.PDAFomi.set_use_global_obs`. + Currently, it only supports 2D limitations. + + See `relevant PDAF wiki page `_ + + + Parameters + ---------- + lim_coords : ndarray[tuple[2, 2, ...], np.float64] + geographic coordinate array (1: longitude, 2: latitude) + """ + with nogil: + c__pdafomi_set_domain_limits(&lim_coords[0,0]) + + + +def get_domain_limits_unstr(int npoints_p, double [::1,:] coords_p): + r"""get_domain_limits_unstr(npoints_p: int, coords_p: np.ndarray) -> None + + Set the domain limits for unstructured domain decomposed local domain. + + This is for the use of :func:`pyPDAF.PDAFomi.set_use_global_obs`. + Currently, it only supports 2D limitations. + + See also `relevant PDAF wiki page `_ + + Parameters + ---------- + npoints_p : int + number of process-local grid points + coords_p : ndarray[np.float64, ndim=2] + geographic coordinate array, dimension (2, npoints_p) + (row 1: longitude, 2: latitude) + ranges: longitude (-pi, pi), latitude (-pi/2, pi/2) + Array shape: (:,:) + """ + cdef CFI_cdesc_rank2 coords_p_cfi + cdef CFI_cdesc_t *coords_p_ptr = &coords_p_cfi + cdef size_t coords_p_nbytes = coords_p.nbytes + cdef CFI_index_t coords_p_extent[2] + coords_p_extent[0] = coords_p.shape[0] + coords_p_extent[1] = coords_p.shape[1] + with nogil: + CFI_establish(coords_p_ptr, &coords_p[0,0], CFI_attribute_other, + CFI_type_double , coords_p_nbytes, 2, coords_p_extent) + + c__pdafomi_get_domain_limits_unstr(&npoints_p, coords_p_ptr) + + + +def store_obs_l_index(int i_obs, int idx, int id_obs_l, + double distance, double cradius_l, double sradius_l): + r"""store_obs_l_index(i_obs: int, idx: int, id_obs_l: int, distance: float, cradius_l: float, sradius_l: float) -> None + + Save local observation information in PDAF. + + One should check `relevant PDAF wiki page `_ + before using this function. + + Parameters + ---------- + i_obs : int + index into observation arrays + idx : int + index of the valid local observations in current local analysis domain + id_obs_l : int + Index of local observation in full observation array + distance : double + Distance between local analysis domain and observation + cradius_l : double + cut-off radius for this local observation + sradius_l : double + support radius for this local observation + """ + with nogil: + c__pdafomi_store_obs_l_index(&i_obs, &idx, &id_obs_l, &distance, + &cradius_l, &sradius_l) + + + +def store_obs_l_index_vdist(int i_obs, int idx, int id_obs_l, + double distance, double cradius_l, double sradius_l, double vdist): + r"""store_obs_l_index_vdist(i_obs: int, idx: int, id_obs_l: int, distance: float, cradius_l: float, sradius_l: float, vdist: float) -> None + + Save local observation information for 2+1D factorized localization in the vertical direction in PDAF. + + One should check `relevant PDAF wiki page `_ + before using this function. + + Parameters + ---------- + i_obs : int + index into observation arrays + idx : int + index of the valid local observations in current local analysis domain + id_obs_l : int + Index of local observation in full observation array + distance : double + Distance between local analysis domain and observation + cradius_l : double + cut-off radius for this local observation + sradius_l : double + support radius for this local observation + vdist : double + support radius in vertical direction for 2+1D factorized localization + """ + with nogil: + c__pdafomi_store_obs_l_index_vdist(&i_obs, &idx, &id_obs_l, + &distance, &cradius_l, + &sradius_l, &vdist) + + + diff --git a/pyPDAF/source/src/pyPDAF/PDAFomi/assim.pxd b/pyPDAF/source/src/pyPDAF/PDAFomi/assim.pxd new file mode 100644 index 0000000000000000000000000000000000000000..71c127771971a0b9226be4f5fbe6de3f09b23f25 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFomi/assim.pxd @@ -0,0 +1,381 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t +cdef extern void c__pdafomi_assimilate_local_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_assimilate_global_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_assimilate_enkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_assimilate_lenkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__localize_covar_pdaf)(int* , int* , double* , double* ), + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_assimilate_nonlin_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__likelihood_pdaf)(int* , int* , double* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_assimilate_lnetf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_assimilate_lknetf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__prodrinva_hyb_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* , double* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__likelihood_hyb_l_pdaf)(int* , int* , int* , double* , + double* , double* , double* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_assimilate_local( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_assimilate_global( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_assimilate_lenkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__localize_covar_pdaf)(int* , int* , double* , double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_assimilate_ensrf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__localize_covar_serial_pdaf)(int* , int* , int* , double* , + double* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_assimilate_3dvar( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_assimilate_en3dvar_estkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_assimilate_en3dvar_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_assimilate_hyb3dvar_estkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_assimilate_hyb3dvar_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_assimilate_3dvar_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_assimilate_en3dvar_estkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_assimilate_en3dvar_lestkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_assimilate_hyb3dvar_estkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_assimilate_hyb3dvar_lestkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_generate_obs( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__distribute_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__get_obs_f_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__next_observation_pdaf)(int* , int* , int* , double* ), + int* outflag) noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/PDAFomi/assim.pyx b/pyPDAF/source/src/pyPDAF/PDAFomi/assim.pyx new file mode 100644 index 0000000000000000000000000000000000000000..9ee7da450f6b20326238444cc21a94cd6691492c --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFomi/assim.pyx @@ -0,0 +1,7167 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + +try: + import mpi4py + mpi4py.rc.initialize = False +except ImportError: + pass + +# Global error handler +def global_except_hook(exctype, value, traceback): + from traceback import print_exception + try: + import mpi4py.MPI + + if mpi4py.MPI.Is_initialized(): + try: + sys.stderr.write('Uncaught exception was ''detected on rank {}.\n'.format( + mpi4py.MPI.COMM_WORLD.Get_rank())) + print_exception(exctype, value, traceback) + sys.stderr.write("\n") + sys.stderr.flush() + finally: + try: + mpi4py.MPI.COMM_WORLD.Abort(1) + except Exception as e: + sys.stderr.write('MPI Abort failed, this process will hang.\n') + sys.stderr.flush() + raise e + else: + sys.__excepthook__(exctype, value, traceback) + except ImportError: + sys.__excepthook__(exctype, value, traceback) + +sys.excepthook = global_except_hook + +def assimilate_local_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prepoststep_pdaf, py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prodrinva_l_pdaf, py__g2l_state_pdaf, + py__l2g_state_pdaf, py__next_observation_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__prodrinva_l_pdaf : Callable + Provide product of inverse of R with matrix A + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from local state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_local_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_global_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prodrinva_pdaf, py__prepoststep_pdaf, py__next_observation_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_global_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_enkf_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__add_obs_err_pdaf, py__init_obs_covar_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__add_obs_err_pdaf : Callable + Add observation error covariance matrix + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Dimension of observation vector + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + py__init_obs_covar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs : int + Global size of observation vector + dim_obs_p : int + Size of process-local observation vector + obs_p : ndarray[np.float64, ndim=1] + Process-local vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + covar : ndarray[np.float64, ndim=2] + Observation error covariance matrix + Array shape: (dim_obs_p,dim_obs_p) + isdiag : bint + + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_enkf_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_lenkf_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prepoststep_pdaf, py__localize_covar_pdaf, py__add_obs_err_pdaf, + py__init_obs_covar_pdaf, py__next_observation_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__localize_covar_pdaf : Callable + Apply localization to HP and HPH^T + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + dim_obs : int + number of observations + hp_p : ndarray[np.float64, ndim=2] + pe local part of matrix hp + Array shape: (dim_obs, dim_p) + hph : ndarray[np.float64, ndim=2] + matrix hph + Array shape: (dim_obs, dim_obs) + + Callback Returns + ---------------- + hp_p : ndarray[np.float64, ndim=2] + pe local part of matrix hp + Array shape: (dim_obs, dim_p) + hph : ndarray[np.float64, ndim=2] + matrix hph + Array shape: (dim_obs, dim_obs) + + py__add_obs_err_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Dimension of observation vector + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + py__init_obs_covar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs : int + Global size of observation vector + dim_obs_p : int + Size of process-local observation vector + obs_p : ndarray[np.float64, ndim=1] + Process-local vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + covar : ndarray[np.float64, ndim=2] + Observation error covariance matrix + Array shape: (dim_obs_p,dim_obs_p) + isdiag : bint + + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.localize_covar_pdaf = py__localize_covar_pdaf + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_lenkf_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__localize_covar_pdaf, + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_nonlin_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__likelihood_pdaf, py__prepoststep_pdaf, py__next_observation_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__likelihood_pdaf : Callable + Compute likelihood + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + resid : ndarray[np.float64, ndim=1] + Input vector holding the residual + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + likely : double + Output value of the likelihood + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.likelihood_pdaf = py__likelihood_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_nonlin_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__likelihood_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_lnetf_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prepoststep_pdaf, py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__likelihood_l_pdaf, py__g2l_state_pdaf, + py__l2g_state_pdaf, py__next_observation_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__likelihood_l_pdaf : Callable + Compute likelihood and apply localization + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from local state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_lnetf_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_lknetf_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prepoststep_pdaf, py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prodrinva_l_pdaf, + py__prodrinva_hyb_l_pdaf, py__likelihood_l_pdaf, + py__likelihood_hyb_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__next_observation_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__prodrinva_hyb_l_pdaf : Callable + Product R^-1 A on local analysis domain with hybrid weight + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + dim_ens : int + Number of the columns in the matrix processes here. This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, dim_ens) + + py__likelihood_l_pdaf : Callable + Compute likelihood and apply localization + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__likelihood_hyb_l_pdaf : Callable + Compute likelihood and apply localization with tempering + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from local state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.prodrinva_hyb_l_pdaf = py__prodrinva_hyb_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.likelihood_hyb_l_pdaf = py__likelihood_hyb_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_lknetf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__prodrinva_hyb_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__likelihood_hyb_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_local(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, py__prepoststep_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__next_observation_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from local state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_local(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assimilate_global(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_global(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assimilate_lenkf(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__prepoststep_pdaf, + py__localize_covar_pdaf, py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_assimilate_lenkf` + or :func:`pyPDAF.PDAF.omi_assimilate_lenkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Stochastic EnKF (ensemble Kalman filter) + with covariance localisation [1]_ + for a single DA step without OMI. + + This is the only scheme for covariance localisation in PDAF. + + This function should be called at each model time step. + The function is a combination of + :func:`pyPDAF.PDAF.put_state_lenkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. py__localize_pdaf + 6. py__add_obs_err_pdaf + 7. py__init_obs_pdaf + 8. py__init_obscovar_pdaf + 9. py__obs_op_pdaf (repeated to reduce storage) + 10. core DA algorith + 11. py__prepoststep_state_pdaf + 12. py__distribute_state_pdaf + 13. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_assimilate_lenkf` + and :func:`pyPDAF.PDAF.omi_assimilate_lenkf_nondiagR` + + References + ---------- + .. [1] Houtekamer, P. L., and H. L. Mitchell (1998): + Data Assimilation Using an Ensemble Kalman Filter + Technique. + Mon. Wea. Rev., 126, 796–811, + doi: 10.1175/1520-0493(1998)126<0796:DAUAEK>2.0.CO;2. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__localize_covar_pdaf : Callable + Apply localization to HP and HPH^T + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + dim_obs : int + number of observations + hp_p : ndarray[np.float64, ndim=2] + pe local part of matrix hp + Array shape: (dim_obs, dim_p) + hph : ndarray[np.float64, ndim=2] + matrix hph + Array shape: (dim_obs, dim_obs) + + Callback Returns + ---------------- + hp_p : ndarray[np.float64, ndim=2] + pe local part of matrix hp + Array shape: (dim_obs, dim_p) + hph : ndarray[np.float64, ndim=2] + matrix hph + Array shape: (dim_obs, dim_obs) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.localize_covar_pdaf = py__localize_covar_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_lenkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__localize_covar_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assimilate_ensrf(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__prepoststep_pdaf, + py__localize_covar_serial_pdaf, py__next_observation_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__localize_covar_serial_pdaf : Callable + Apply localization to HP and BXY + + Callback Parameters + ------------------- + iobs : int + Index of current observation + dim_p : int + Process-local state dimension + dim_obs : int + Number of observations + hp_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HP for observation iobs + Array shape: (dim_p) + hxy_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HX(HX_all) for full observations + Array shape: (dim_obs) + + Callback Returns + ---------------- + hp_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HP for observation iobs + Array shape: (dim_p) + hxy_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HX(HX_all) for full observations + Array shape: (dim_obs) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.localize_covar_serial_pdaf = py__localize_covar_serial_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_ensrf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__localize_covar_serial_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assimilate_3dvar(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_assimilate_3dvar` + or :func:`pyPDAF.PDAF.omi_assimilate_3dvar_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + 3DVar DA for a single step without OMI. + When 3DVar is used, the background error covariance matrix + has to be modelled for cotrol variable + transformation. This is a deterministic filtering + scheme so no ensemble and + parallelisation is needed. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_3dvar` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. Iterative optimisation: + 1. py__cvt_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_pdaf + 6. core DA algorithm + 7. py__cvt_pdaf + 8. py__prepoststep_state_pdaf + 9. py__distribute_state_pdaf + 10. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by :func:`pyPDAF.PDAF.omi_assimilate_3dvar` + and :func:`pyPDAF.PDAF.omi_assimilate_3dvar_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_3dvar(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + +def assimilate_en3dvar_estkf(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__prepoststep_pdaf, py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_assimilate_en3dvar_estkf` + or :func:`pyPDAF.PDAF.omi_assimilate_en3dvar_estkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + 3DEnVar for a single DA step. + The background error covariance matrix is estimated + by an ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An ESTKF is used along with 3DEnVar + to generate ensemble perturbations. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_en3dvar_estkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core 3DEnVar algorithm + 7. py__cvt_ens_pdaf + 8. ESTKF: + 1. py__init_dim_obs_pdaf + 2. py__obs_op_pdaf (for ensemble mean) + 3. py__init_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. py__init_obsvar_pdaf + (only relevant for adaptive + forgetting factor schemes) + 6. py__prodRinvA_pdaf + 7. core ESTKF algorithm + 9. py__prepoststep_state_pdaf + 10. py__distribute_state_pdaf + 11. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_assimilate_en3dvar_estkf` + and :func:`pyPDAF.PDAF.omi_assimilate_en3dvar_estkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_en3dvar_estkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_en3dvar_lestkf(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__prepoststep_pdaf, py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf` or + :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + 3DEnVar for a single DA step where the ensemble anomaly + is generated by LESTKF. + The background error covariance matrix is + estimated by ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An LESTKF is used to generate ensemble perturbations. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_en3dvar_lestkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. Starting the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core DA algorithm + 7. py__cvt_ens_pdaf + 8. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__init_obs_pdaf + (if global adaptive forgetting factor is used + `type_forget=1` in :func:`pyPDAF.PDAF.init`) + 5. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise mean ensemble in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local + adaptive forgetting factor + `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + 9. py__prepoststep_state_pdaf + 10. py__distribute_state_pdaf + 11. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf` + and + :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from local state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_en3dvar_lestkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_hyb3dvar_estkf(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_assimilate_hyb3dvar_estkf` + or :func:`pyPDAF.PDAF.omi_assimilate_hyb3dvar_estkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Hybrid 3DEnVar for a single DA step where + the background error covariance is hybridised by + a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + ESTKF in this implementation. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_hyb3dvar_estkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. the iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core 3DEnVar algorithm + 7. py__cvt_pdaf + 8. py__cvt_ens_pdaf + 9. Perform ESTKF: + 1. py__init_dim_obs_pdaf + 2. py__obs_op_pdaf + (for ensemble mean) + 3. py__init_obs_pdaf + 4. py__obs_op_pdaf + (for each ensemble member) + 5. py__init_obsvar_pdaf + (only relevant for adaptive + forgetting factor schemes) + 6. py__prodRinvA_pdaf + 7. core ESTKF algorithm + 10. py__prepoststep_state_pdaf + 11. py__distribute_state_pdaf + 12. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_assimilate_hyb3dvar_estkf` and + :func:`pyPDAF.PDAF.omi_assimilate_hyb3dvar_estkf_nondiagR`. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__cvt_ens_pdaf : Callable + Apply ensemble control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint ensemble control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_hyb3dvar_estkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_hyb3dvar_lestkf(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, + py__l2g_state_pdaf, py__prepoststep_pdaf, py__next_observation_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf` or + :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Hybrid 3DEnVar for a single DA step where + the background error covariance is hybridised by + a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + LESTKF in this implementation. + This function should be called at each model time step. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_hyb3dvar_lestkf` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. The iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core DA algorithm + 7. py__cvt_pdaf + 8. py__cvt_ens_pdaf + 9. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__init_obs_pdaf + (if global adaptive forgetting factor + `type_forget=1` in :func:`pyPDAF.PDAF.init`) + 5. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise mean ensemble in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting + factor `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + 10. py__prepoststep_state_pdaf + 11. py__distribute_state_pdaf + 12. py__next_observation_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf` + and + :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from local state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_hyb3dvar_lestkf( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_3dvar_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prodrinva_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_3dvar_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_en3dvar_estkf_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prodrinva_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prepoststep_pdaf, + py__next_observation_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_en3dvar_estkf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_en3dvar_lestkf_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prodrinva_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prodrinva_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__prepoststep_pdaf, py__next_observation_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A with localization + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from local state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_en3dvar_lestkf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_hyb3dvar_estkf_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prodrinva_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__cvt_pdaf, py__cvt_adj_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__prepoststep_pdaf, py__next_observation_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply ensemble control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint ensemble control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_hyb3dvar_estkf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def assimilate_hyb3dvar_lestkf_nondiagr(py__collect_state_pdaf, + py__distribute_state_pdaf, py__init_dim_obs_pdaf, py__obs_op_pdaf, + py__prodrinva_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__cvt_pdaf, py__cvt_adj_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, + py__l2g_state_pdaf, py__prepoststep_pdaf, py__next_observation_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from local state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + cdef int outflag + with nogil: + c__pdafomi_assimilate_hyb3dvar_lestkf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, + &outflag) + + return outflag + + +def generate_obs(py__collect_state_pdaf, py__distribute_state_pdaf, + py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, py__get_obs_f_pdaf, + py__prepoststep_pdaf, py__next_observation_pdaf, int outflag): + """Generation of synthetic observations based on + given error statistics and observation operator. + + When diagonal observation error covariance matrix is used, + it is recommended to use + :func:`pyPDAF.PDAF.omi_generate_obs` functionalities + for fewer user-supplied functions and improved efficiency. + + The generated synthetic observations are based on + each member of model forecast. + Therefore, an ensemble of observations can be obtained. + In a typical experiment, + one may only need one ensemble member. + The implementation strategy is similar to + an assimilation step. This means that, + one can reuse many user-supplied functions for + assimilation and observation generation. + + The function is a combination of + :func:`pyPDAF.PDAF.put_state_generate_obs` + and :func:`pyPDAF.PDAF.get_state`. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pda + 5. py__init_obserr_f_pdaf + 6. py__get_obs_f_pdaf + 7. py__prepoststep_state_pdaf + 8. py__distribute_state_pdaf + 9. py__next_observation_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__distribute_state_pdaf : Callable + Routine to distribute a state vector + + Callback Parameters + ------------------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__get_obs_f_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Size of the full observation vector + + Callback Returns + ---------------- + observation_f : ndarray[np.float64, ndim=1] + Full vector of synthetic observations (process-local) + Array shape: (dim_obs_f) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__next_observation_pdaf : Callable + Provide time step, time and dimension of next observation + + Callback Parameters + ------------------- + stepnow : int + the current time step given by PDAF + + Callback Returns + ---------------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.distribute_state_pdaf = py__distribute_state_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.get_obs_f_pdaf = py__get_obs_f_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.next_observation_pdaf = py__next_observation_pdaf + with nogil: + c__pdafomi_generate_obs(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__distribute_state_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__get_obs_f_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__next_observation_pdaf, &outflag) + + return outflag + + diff --git a/pyPDAF/source/src/pyPDAF/PDAFomi/diag.pxd b/pyPDAF/source/src/pyPDAF/PDAFomi/diag.pxd new file mode 100644 index 0000000000000000000000000000000000000000..b6a63b08edffc0010aa665dfc622ce71db4776a3 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFomi/diag.pxd @@ -0,0 +1,26 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t +cdef extern void c__pdafomi_diag_dimobs( + CFI_cdesc_t* dim_obs_ptr) noexcept nogil; + +cdef extern void c__pdafomi_diag_get_hx(int* id_obs, int* dim_obs_diag, + CFI_cdesc_t* hx_p_ptr) noexcept nogil; + +cdef extern void c__pdafomi_diag_get_hxmean(int* id_obs, int* dim_obs_diag, + CFI_cdesc_t* hxmean_p_ptr) noexcept nogil; + +cdef extern void c__pdafomi_diag_get_ivar(int* id_obs, int* dim_obs_diag, + CFI_cdesc_t* ivar_ptr) noexcept nogil; + +cdef extern void c__pdafomi_diag_get_obs(int* id_obs, int* dim_obs_diag, + int* ncoord, CFI_cdesc_t* obs_p_ptr, + CFI_cdesc_t* ocoord_p_ptr) noexcept nogil; + +cdef extern void c__pdafomi_diag_nobstypes( + int* nobs) noexcept nogil; + +cdef extern void c__pdafomi_diag_obs_rmsd(int* nobs, + CFI_cdesc_t* rmsd_pointer, int* verbose) noexcept nogil; + +cdef extern void c__pdafomi_diag_stats(int* nobs, + CFI_cdesc_t* obsstats_ptr, int* verbose) noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/PDAFomi/diag.pyi b/pyPDAF/source/src/pyPDAF/PDAFomi/diag.pyi new file mode 100644 index 0000000000000000000000000000000000000000..6a33e1a921e44a4b2c6d1bacbde58d22dabd1e4f --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFomi/diag.pyi @@ -0,0 +1,149 @@ +# pylint: disable=unused-argument +"""Stub file for PDAFomi diag module +""" +from typing import Tuple +import numpy as np + + +def diag_dimobs() -> np.ndarray: + """Observation dimension for each observation type. + + Returns + ------- + dim_obs: np.ndarray + Observation dimension for each observation type. shape: (n_obs,) + """ + +def diag_get_hx(id_obs: int) -> Tuple[int, np.ndarray]: + """Observed ensemble for given observation type. + + Parameters + ---------- + id_obs : int + Index of observation type to return + + Returns + ------- + dim_obs_diag : int + Observation dimension + hx_p_ptr : ndarray[np.float64, ndim=2] + Pointer to observed ensemble mean + Array shape: (dim_obs_p_diag, dim_ens) + """ + +def diag_get_hxmean(id_obs: int) -> Tuple[int, np.ndarray]: + """Observed ensemble mean for given observation type. + + Parameters + ---------- + id_obs : int + Index of observation type to return + + Returns + ------- + dim_obs_diag : int + Observation dimension + hxmean_p_ptr : ndarray[np.float64, ndim=1] + Pointer to observed ensemble mean + Array shape: (:) + """ + +def diag_get_ivar(id_obs: int) -> Tuple[int, np.ndarray]: + """Inverse of observation error variance for given observation type. + + Parameters + ---------- + id_obs : int + Index of observation type to return + + Returns + ------- + dim_obs_diag : int + Observation dimension + ivar_ptr : ndarray[np.float64, ndim=1] + Pointer to inverse observation error variances + Array shape: (:) + """ + +def diag_get_obs(id_obs: int) -> Tuple[int, int, np.ndarray, np.ndarray]: + """Observation vector and corresponding coordinates for specified observation type. + + Parameters + ---------- + id_obs : int + Index of observation type to return + + Returns + ------- + dim_obs_diag : int + Observation dimension + ncoord : int + Number of observation dimensions + obs_p_ptr : ndarray[np.float64, ndim=1] + Pointer to observation vector + Array shape: (:) + ocoord_p_ptr : ndarray[np.float64, ndim=2] + Pointer to Coordinate array + Array shape: (:,:) + """ + +def diag_nobstypes(nobs: int) -> int: + """The number of observation types that are active in an assimilation run. + + Parameters + ---------- + nobs : int + Number of observation types (input can be an arbitrary number) + + Returns + ------- + nobs : int + Number of observation types + """ + +def diag_obs_rmsd(nobs: int, verbose: int) -> Tuple[int, np.ndarray]: + """Root mean squared distance between observation and obseved model state + for each observation type. + + Parameters + ---------- + nobs : int + Number of observation types + verbose : int + Verbosity flag + + Returns + ------- + nobs : int + Number of observation types + rmsd_pointer : ndarray[np.float64, ndim=1] + Vector of RMSD values + Array shape: (:) + """ + +def diag_stats(nobs: int, verbose: int) -> Tuple[int, np.ndarray]: + """A selection of 6 statistics comparing the observations and the + observed ensemble mean for each observation type. + + Parameters + ---------- + nobs : int + Number of observation types + verbose : int + Verbosity flag + + Returns + ------- + nobs : int + Number of observation types + obsstats_ptr : ndarray[np.float64, ndim=2] + Array of observation statistics + Included statistics are: + - (1,:) correlations between observation and observed ensemble mean + - (2,:) centered RMS difference between observation and observed ensemble mean + - (3,:) mean bias (observation minus observed ensemble mean) + - (4,:) mean absolute difference between observation and observed ensemble mean + - (5,:) variance of observations + - (6,:) variance of observed ensemble mean + Array shape: (:,:) + """ diff --git a/pyPDAF/source/src/pyPDAF/PDAFomi/diag.pyx b/pyPDAF/source/src/pyPDAF/PDAFomi/diag.pyx new file mode 100644 index 0000000000000000000000000000000000000000..063e70ba92515831ec5b7f3722adbb01ece13ce9 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFomi/diag.pyx @@ -0,0 +1,272 @@ +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + + +def diag_dimobs(): + """diag_dimobs() -> np.ndarray + + Observation dimension for each observation type. + + Returns + ------- + dim_obs: np.ndarray + Observation dimension for each observation type. shape: (n_obs,) + """ + cdef CFI_cdesc_rank1 dim_obs_ptr_cfi + cdef CFI_cdesc_t *dim_obs_ptr_ptr = &dim_obs_ptr_cfi + with nogil: + c__pdafomi_diag_dimobs(dim_obs_ptr_ptr) + + cdef CFI_index_t dim_obs_ptr_subscripts[1] + dim_obs_ptr_subscripts[0] = 0 + cdef int * dim_obs_ptr_ptr_np + dim_obs_ptr_ptr_np = CFI_address(dim_obs_ptr_ptr, dim_obs_ptr_subscripts) + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] dim_obs_ptr_np = np.asarray( dim_obs_ptr_ptr_np, order="F") + return dim_obs_ptr_np + + +def diag_get_hx(int id_obs): + """diag_get_hx(id_obs: int) -> Tuple[int, np.ndarray] + + Observed ensemble for given observation type. + + Parameters + ---------- + id_obs : int + Index of observation type to return + + Returns + ------- + dim_obs_diag : int + Observation dimension + hx_p_ptr : ndarray[np.float64, ndim=2] + Pointer to observed ensemble mean + Array shape: (dim_obs_p_diag, dim_ens) + """ + cdef CFI_cdesc_rank2 hx_p_ptr_cfi + cdef CFI_cdesc_t *hx_p_ptr_ptr = &hx_p_ptr_cfi + cdef int dim_obs_diag + with nogil: + c__pdafomi_diag_get_hx(&id_obs, &dim_obs_diag, hx_p_ptr_ptr) + + cdef CFI_index_t hx_p_ptr_subscripts[2] + hx_p_ptr_subscripts[0] = 0 + hx_p_ptr_subscripts[1] = 0 + cdef double * hx_p_ptr_ptr_np + hx_p_ptr_ptr_np = CFI_address(hx_p_ptr_ptr, hx_p_ptr_subscripts) + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hx_p_ptr_np = np.asarray( hx_p_ptr_ptr_np, order="F") + return dim_obs_diag, hx_p_ptr_np + + +def diag_get_hxmean(int id_obs): + """diag_get_hxmean(id_obs: int) -> Tuple[int, np.ndarray] + + Observed ensemble mean for given observation type. + + Parameters + ---------- + id_obs : int + Index of observation type to return + + Returns + ------- + dim_obs_diag : int + Observation dimension + hxmean_p_ptr : ndarray[np.float64, ndim=1] + Pointer to observed ensemble mean + Array shape: (:) + """ + cdef CFI_cdesc_rank1 hxmean_p_ptr_cfi + cdef CFI_cdesc_t *hxmean_p_ptr_ptr = &hxmean_p_ptr_cfi + cdef int dim_obs_diag + with nogil: + c__pdafomi_diag_get_hxmean(&id_obs, &dim_obs_diag, hxmean_p_ptr_ptr) + + cdef CFI_index_t hxmean_p_ptr_subscripts[1] + hxmean_p_ptr_subscripts[0] = 0 + cdef double * hxmean_p_ptr_ptr_np + hxmean_p_ptr_ptr_np = CFI_address(hxmean_p_ptr_ptr, hxmean_p_ptr_subscripts) + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] hxmean_p_ptr_np = np.asarray( hxmean_p_ptr_ptr_np, order="F") + return dim_obs_diag, hxmean_p_ptr_np + + +def diag_get_ivar(int id_obs): + """diag_get_ivar(id_obs: int) -> Tuple[int, np.ndarray] + + Inverse of observation error variance for given observation type. + + Parameters + ---------- + id_obs : int + Index of observation type to return + + Returns + ------- + dim_obs_diag : int + Observation dimension + ivar_ptr : ndarray[np.float64, ndim=1] + Pointer to inverse observation error variances + Array shape: (:) + """ + cdef CFI_cdesc_rank1 ivar_ptr_cfi + cdef CFI_cdesc_t *ivar_ptr_ptr = &ivar_ptr_cfi + cdef int dim_obs_diag + with nogil: + c__pdafomi_diag_get_ivar(&id_obs, &dim_obs_diag, ivar_ptr_ptr) + + cdef CFI_index_t ivar_ptr_subscripts[1] + ivar_ptr_subscripts[0] = 0 + cdef double * ivar_ptr_ptr_np + ivar_ptr_ptr_np = CFI_address(ivar_ptr_ptr, ivar_ptr_subscripts) + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] ivar_ptr_np = np.asarray( ivar_ptr_ptr_np, order="F") + return dim_obs_diag, ivar_ptr_np + + +def diag_get_obs(int id_obs): + """diag_get_obs(id_obs: int) -> Tuple[int, int, np.ndarray, np.ndarray] + + Observation vector and corresponding coordinates for specified observation type. + + Parameters + ---------- + id_obs : int + Index of observation type to return + + Returns + ------- + dim_obs_diag : int + Observation dimension + ncoord : int + Number of observation dimensions + obs_p_ptr : ndarray[np.float64, ndim=1] + Pointer to observation vector + Array shape: (:) + ocoord_p_ptr : ndarray[np.float64, ndim=2] + Pointer to Coordinate array + Array shape: (:,:) + """ + cdef CFI_cdesc_rank1 obs_p_ptr_cfi + cdef CFI_cdesc_t *obs_p_ptr_ptr = &obs_p_ptr_cfi + cdef CFI_cdesc_rank2 ocoord_p_ptr_cfi + cdef CFI_cdesc_t *ocoord_p_ptr_ptr = &ocoord_p_ptr_cfi + cdef int dim_obs_diag + cdef int ncoord + with nogil: + c__pdafomi_diag_get_obs(&id_obs, &dim_obs_diag, &ncoord, + obs_p_ptr_ptr, ocoord_p_ptr_ptr) + + cdef CFI_index_t obs_p_ptr_subscripts[1] + obs_p_ptr_subscripts[0] = 0 + cdef double * obs_p_ptr_ptr_np + obs_p_ptr_ptr_np = CFI_address(obs_p_ptr_ptr, obs_p_ptr_subscripts) + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obs_p_ptr_np = np.asarray( obs_p_ptr_ptr_np, order="F") + cdef CFI_index_t ocoord_p_ptr_subscripts[2] + ocoord_p_ptr_subscripts[0] = 0 + ocoord_p_ptr_subscripts[1] = 0 + cdef double * ocoord_p_ptr_ptr_np + ocoord_p_ptr_ptr_np = CFI_address(ocoord_p_ptr_ptr, ocoord_p_ptr_subscripts) + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] ocoord_p_ptr_np = np.asarray( ocoord_p_ptr_ptr_np, order="F") + return dim_obs_diag, ncoord, obs_p_ptr_np, ocoord_p_ptr_np + + +def diag_nobstypes(int nobs): + """diag_nobstypes(nobs: int) -> int + + The number of observation types that are active in an assimilation run. + + Parameters + ---------- + nobs : int + Number of observation types (input can be an arbitrary number) + + Returns + ------- + nobs : int + Number of observation types + """ + with nogil: + c__pdafomi_diag_nobstypes(&nobs) + + return nobs + + +def diag_obs_rmsd(int nobs, int verbose): + """diag_obs_rmsd(nobs: int, verbose: int) -> Tuple[int, np.ndarray] + + Root mean squared distance between observation and obseved model state + for each observation type. + + Parameters + ---------- + nobs : int + Number of observation types + verbose : int + Verbosity flag + + Returns + ------- + nobs : int + Number of observation types + rmsd_pointer : ndarray[np.float64, ndim=1] + Vector of RMSD values + Array shape: (:) + """ + cdef CFI_cdesc_rank1 rmsd_pointer_cfi + cdef CFI_cdesc_t *rmsd_pointer_ptr = &rmsd_pointer_cfi + with nogil: + c__pdafomi_diag_obs_rmsd(&nobs, rmsd_pointer_ptr, &verbose) + + cdef CFI_index_t rmsd_pointer_subscripts[1] + rmsd_pointer_subscripts[0] = 0 + cdef double * rmsd_pointer_ptr_np + rmsd_pointer_ptr_np = CFI_address(rmsd_pointer_ptr, rmsd_pointer_subscripts) + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] rmsd_pointer_np = np.asarray( rmsd_pointer_ptr_np, order="F") + return nobs, rmsd_pointer_np + + +def diag_stats(int nobs, int verbose): + """diag_stats(nobs: int, verbose: int) -> Tuple[int, np.ndarray] + + A selection of 6 statistics comparing the observations and the + observed ensemble mean for each observation type. + + Parameters + ---------- + nobs : int + Number of observation types + verbose : int + Verbosity flag + + Returns + ------- + nobs : int + Number of observation types + obsstats_ptr : ndarray[np.float64, ndim=2] + Array of observation statistics + Included statistics are: + - (1,:) correlations between observation and observed ensemble mean + - (2,:) centered RMS difference between observation and observed ensemble mean + - (3,:) mean bias (observation minus observed ensemble mean) + - (4,:) mean absolute difference between observation and observed ensemble mean + - (5,:) variance of observations + - (6,:) variance of observed ensemble mean + Array shape: (:,:) + """ + cdef CFI_cdesc_rank2 obsstats_ptr_cfi + cdef CFI_cdesc_t *obsstats_ptr_ptr = &obsstats_ptr_cfi + with nogil: + c__pdafomi_diag_stats(&nobs, obsstats_ptr_ptr, &verbose) + + cdef CFI_index_t obsstats_ptr_subscripts[2] + obsstats_ptr_subscripts[0] = 0 + obsstats_ptr_subscripts[1] = 0 + cdef double * obsstats_ptr_ptr_np + obsstats_ptr_ptr_np = CFI_address(obsstats_ptr_ptr, obsstats_ptr_subscripts) + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] obsstats_ptr_np = np.asarray( obsstats_ptr_ptr_np, order="F") + return nobs, obsstats_ptr_np + + diff --git a/pyPDAF/source/src/pyPDAF/PDAFomi/internal.pxd b/pyPDAF/source/src/pyPDAF/PDAFomi/internal.pxd new file mode 100644 index 0000000000000000000000000000000000000000..53b2894fe8f0f7d8b2c785cf313211f673b3ec1a --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFomi/internal.pxd @@ -0,0 +1,155 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t +cdef extern void c__pdafomi_set_globalobs( + int* globalobs_in) noexcept nogil; + +cdef extern void c__pdafomi_diag_omit_by_inno() noexcept nogil; + +cdef extern void c__pdafomi_cnt_dim_obs_l(int* i_obs, + CFI_cdesc_t* coords_l) noexcept nogil; + +cdef extern void c__pdafomi_cnt_dim_obs_l_noniso(int* i_obs, + CFI_cdesc_t* coords_l) noexcept nogil; + +cdef extern void c__pdafomi_init_obsarrays_l(int* i_obs, + CFI_cdesc_t* coords_l, int* off_obs_l_all) noexcept nogil; + +cdef extern void c__pdafomi_init_obsarrays_l_noniso(int* i_obs, + CFI_cdesc_t* coords_l, int* off_obs_l_all) noexcept nogil; + +cdef extern void c__pdafomi_g2l_obs(int* i_obs, CFI_cdesc_t* obs_f_all, + CFI_cdesc_t* obs_l_all) noexcept nogil; + +cdef extern void c__pdafomi_init_obs_l(int* i_obs, + CFI_cdesc_t* obs_l_all) noexcept nogil; + +cdef extern void c__pdafomi_init_obsvar_l(int* i_obs, double* meanvar_l, + int* cnt_obs_l) noexcept nogil; + +cdef extern void c__pdafomi_prodrinva_l(int* i_obs, int* nobs_all, + int* ncols, CFI_cdesc_t* a_l, CFI_cdesc_t* c_l, + int* verbose) noexcept nogil; + +cdef extern void c__pdafomi_prodrinva_hyb_l(int* i_obs, int* nobs_all, + int* ncols, double* gamma, CFI_cdesc_t* a_l, CFI_cdesc_t* c_l, + int* verbose) noexcept nogil; + +cdef extern void c__pdafomi_likelihood_l(int* i_obs, + CFI_cdesc_t* resid_l_all, double* lhood_l, + int* verbose) noexcept nogil; + +cdef extern void c__pdafomi_likelihood_hyb_l(int* i_obs, + CFI_cdesc_t* resid_l_all, double* gamma, double* lhood_l, + int* verbose) noexcept nogil; + +cdef extern void c__pdafomi_g2l_obs_internal(int* i_obs, + CFI_cdesc_t* obs_f_one, int* offset_obs_l_all, + CFI_cdesc_t* obs_l_all) noexcept nogil; + +cdef extern void c__pdafomi_comp_dist2(int* i_obs, CFI_cdesc_t* coordsa, + CFI_cdesc_t* coordsb, double* distance2, + int* verbose) noexcept nogil; + +cdef extern void c__pdafomi_check_dist2(int* i_obs, CFI_cdesc_t* coordsa, + CFI_cdesc_t* coordsb, double* distance2, bint* checkdist, int* verbose, + int* cnt_obs) noexcept nogil; + +cdef extern void c__pdafomi_check_dist2_noniso(int* i_obs, + CFI_cdesc_t* coordsa, CFI_cdesc_t* coordsb, double* distance2, + CFI_cdesc_t* dists, double* cradius, double* sradius, bint* checkdist, + int* verbose, int* cnt_obs) noexcept nogil; + +cdef extern void c__pdafomi_weights_l(int* verbose, int* nobs_l, + int* ncols, int* locweight, CFI_cdesc_t* cradius, CFI_cdesc_t* sradius, + CFI_cdesc_t* mata, CFI_cdesc_t* ivar_obs_l, CFI_cdesc_t* dist_l, + CFI_cdesc_t* weight_l) noexcept nogil; + +cdef extern void c__pdafomi_weights_l_sgnl(int* verbose, int* nobs_l, + int* ncols, int* locweight, double* cradius, double* sradius, + CFI_cdesc_t* mata, CFI_cdesc_t* ivar_obs_l, CFI_cdesc_t* dist_l, + CFI_cdesc_t* weight_l) noexcept nogil; + +cdef extern void c__pdafomi_omit_by_inno_l(int* i_obs, CFI_cdesc_t* inno_l, + CFI_cdesc_t* obs_l_all, int* obsid, int* cnt_all, + int* verbose) noexcept nogil; + +cdef extern void c__pdafomi_obsstats_l( + int* screen) noexcept nogil; + +cdef extern void c__pdafomi_dealloc() noexcept nogil; + +cdef extern void c__pdafomi_ocoord_all(int* ncoord, + CFI_cdesc_t* oc_all) noexcept nogil; + +cdef extern void c__pdafomi_local_weight(int* wtype, int* rtype, + double* cradius, double* sradius, double* distance, int* nrows, + int* ncols, double* a, double* var_obs, double* weight, + int* verbose) noexcept nogil; + +cdef extern void c__pdafomi_check_dist2_loop(int* i_obs, + CFI_cdesc_t* coordsa, int* cnt_obs, + int* mode) noexcept nogil; + +cdef extern void c__pdafomi_check_dist2_noniso_loop(int* i_obs, + CFI_cdesc_t* coordsa, int* cnt_obs, + int* mode) noexcept nogil; + +cdef extern void c__pdafomi_obs_op_gatheronly(int* i_obs, + CFI_cdesc_t* state_p, + CFI_cdesc_t* obs_f_all) noexcept nogil; + +cdef extern void c__pdafomi_obs_op_adj_gatheronly(int* i_obs, + CFI_cdesc_t* obs_f_all, + CFI_cdesc_t* state_p) noexcept nogil; + +cdef extern void c__pdafomi_init_obs_f(int* i_obs, int* dim_obs_f, + CFI_cdesc_t* obsstate_f, int* offset) noexcept nogil; + +cdef extern void c__pdafomi_init_obsvars_f(int* i_obs, int* dim_obs_f, + CFI_cdesc_t* var_f, int* offset) noexcept nogil; + +cdef extern void c__pdafomi_init_obsvar_f(int* i_obs, double* meanvar, + int* cnt_obs) noexcept nogil; + +cdef extern void c__pdafomi_prodrinva(int* i_obs, int* ncols, + CFI_cdesc_t* a_p, CFI_cdesc_t* c_p) noexcept nogil; + +cdef extern void c__pdafomi_likelihood(int* i_obs, CFI_cdesc_t* resid, + double* lhood) noexcept nogil; + +cdef extern void c__pdafomi_add_obs_error(int* i_obs, int* nobs_all, + CFI_cdesc_t* matc) noexcept nogil; + +cdef extern void c__pdafomi_init_obscovar(int* i_obs, int* nobs_all, + CFI_cdesc_t* covar, bint* isdiag) noexcept nogil; + +cdef extern void c__pdafomi_init_obserr_f(int* i_obs, + CFI_cdesc_t* obserr_f) noexcept nogil; + +cdef extern void c__pdafomi_get_local_ids_obs_f(int* dim_obs_g, + double* lradius, CFI_cdesc_t* oc_f, int* cnt_lim, CFI_cdesc_t* id_lim, + int* disttype, CFI_cdesc_t* domainsize) noexcept nogil; + +cdef extern void c__pdafomi_limit_obs_f(int* i_obs, int* offset, + CFI_cdesc_t* obs_f_one, + CFI_cdesc_t* obs_f_lim) noexcept nogil; + +cdef extern void c__pdafomi_gather_dim_obs_f(int* dim_obs_p, + int* dim_obs_f) noexcept nogil; + +cdef extern void c__pdafomi_gather_obs_f_flex(int* dim_obs_p, + CFI_cdesc_t* obs_p, CFI_cdesc_t* obs_f, + int* status) noexcept nogil; + +cdef extern void c__pdafomi_gather_obs_f2_flex(int* dim_obs_p, + CFI_cdesc_t* coords_p, CFI_cdesc_t* coords_f, int* nrows, + int* status) noexcept nogil; + +cdef extern void c__pdafomi_omit_by_inno(int* i_obs, CFI_cdesc_t* inno_f, + CFI_cdesc_t* obs_f_all, int* obsid, + int* cnt_all) noexcept nogil; + +cdef extern void c__pdafomi_obsstats( + int* screen) noexcept nogil; + +cdef extern void c__pdafomi_gather_obsdims() noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/PDAFomi/internal.pyx b/pyPDAF/source/src/pyPDAF/PDAFomi/internal.pyx new file mode 100644 index 0000000000000000000000000000000000000000..a7f7ec056fd5bb1311717040d3117acd9251f144 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFomi/internal.pyx @@ -0,0 +1,1821 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + +try: + import mpi4py + mpi4py.rc.initialize = False +except ImportError: + pass + +# Global error handler +def global_except_hook(exctype, value, traceback): + from traceback import print_exception + try: + import mpi4py.MPI + + if mpi4py.MPI.Is_initialized(): + try: + sys.stderr.write('Uncaught exception was ''detected on rank {}.\n'.format( + mpi4py.MPI.COMM_WORLD.Get_rank())) + print_exception(exctype, value, traceback) + sys.stderr.write("\n") + sys.stderr.flush() + finally: + try: + mpi4py.MPI.COMM_WORLD.Abort(1) + except Exception as e: + sys.stderr.write('MPI Abort failed, this process will hang.\n') + sys.stderr.flush() + raise e + else: + sys.__excepthook__(exctype, value, traceback) + except ImportError: + sys.__excepthook__(exctype, value, traceback) + +sys.excepthook = global_except_hook + +def set_globalobs(int globalobs_in): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + globalobs_in : int + Input value of globalobs + + Returns + ------- + """ + with nogil: + c__pdafomi_set_globalobs(&globalobs_in) + + + +def diag_omit_by_inno(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdafomi_diag_omit_by_inno() + + + +def cnt_dim_obs_l(int i_obs, double [::1] coords_l): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + coords_l : ndarray[np.float64, ndim=1] + Coordinates of current analysis domain (thisobs%ncoord) + Array shape: (:) + + Returns + ------- + """ + cdef CFI_cdesc_rank1 coords_l_cfi + cdef CFI_cdesc_t *coords_l_ptr = &coords_l_cfi + cdef size_t coords_l_nbytes = coords_l.nbytes + cdef CFI_index_t coords_l_extent[1] + coords_l_extent[0] = coords_l.shape[0] + with nogil: + CFI_establish(coords_l_ptr, &coords_l[0], CFI_attribute_other, + CFI_type_double , coords_l_nbytes, 1, coords_l_extent) + + c__pdafomi_cnt_dim_obs_l(&i_obs, coords_l_ptr) + + + +def cnt_dim_obs_l_noniso(int i_obs, double [::1] coords_l): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + coords_l : ndarray[np.float64, ndim=1] + Coordinates of current analysis domain (thisobs%ncoord) + Array shape: (:) + + Returns + ------- + """ + cdef CFI_cdesc_rank1 coords_l_cfi + cdef CFI_cdesc_t *coords_l_ptr = &coords_l_cfi + cdef size_t coords_l_nbytes = coords_l.nbytes + cdef CFI_index_t coords_l_extent[1] + coords_l_extent[0] = coords_l.shape[0] + with nogil: + CFI_establish(coords_l_ptr, &coords_l[0], CFI_attribute_other, + CFI_type_double , coords_l_nbytes, 1, coords_l_extent) + + c__pdafomi_cnt_dim_obs_l_noniso(&i_obs, coords_l_ptr) + + + +def init_obsarrays_l(int i_obs, double [::1] coords_l, int off_obs_l_all): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + coords_l : ndarray[np.float64, ndim=1] + Coordinates of current water column (thisobs%ncoord) + Array shape: (:) + off_obs_l_all : int + input: offset of current obs. in local obs. vector + + Returns + ------- + off_obs_l_all : int + input: offset of current obs. in local obs. vector + """ + cdef CFI_cdesc_rank1 coords_l_cfi + cdef CFI_cdesc_t *coords_l_ptr = &coords_l_cfi + cdef size_t coords_l_nbytes = coords_l.nbytes + cdef CFI_index_t coords_l_extent[1] + coords_l_extent[0] = coords_l.shape[0] + with nogil: + CFI_establish(coords_l_ptr, &coords_l[0], CFI_attribute_other, + CFI_type_double , coords_l_nbytes, 1, coords_l_extent) + + c__pdafomi_init_obsarrays_l(&i_obs, coords_l_ptr, &off_obs_l_all) + + return off_obs_l_all + + +def init_obsarrays_l_noniso(int i_obs, double [::1] coords_l, + int off_obs_l_all): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + coords_l : ndarray[np.float64, ndim=1] + Coordinates of current water column (thisobs%ncoord) + Array shape: (:) + off_obs_l_all : int + input: offset of current obs. in local obs. vector + + Returns + ------- + off_obs_l_all : int + input: offset of current obs. in local obs. vector + """ + cdef CFI_cdesc_rank1 coords_l_cfi + cdef CFI_cdesc_t *coords_l_ptr = &coords_l_cfi + cdef size_t coords_l_nbytes = coords_l.nbytes + cdef CFI_index_t coords_l_extent[1] + coords_l_extent[0] = coords_l.shape[0] + with nogil: + CFI_establish(coords_l_ptr, &coords_l[0], CFI_attribute_other, + CFI_type_double , coords_l_nbytes, 1, coords_l_extent) + + c__pdafomi_init_obsarrays_l_noniso(&i_obs, coords_l_ptr, &off_obs_l_all) + + return off_obs_l_all + + +def g2l_obs(int i_obs, double [::1] obs_f_all, double [::1] obs_l_all): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + obs_f_all : ndarray[np.float64, ndim=1] + Full obs. vector of current obs. for all variables + Array shape: (:) + obs_l_all : ndarray[np.float64, ndim=1] + Local observation vector for all variables + Array shape: (:) + + Returns + ------- + obs_l_all : ndarray[np.float64, ndim=1] + Local observation vector for all variables + Array shape: (:) + """ + cdef CFI_cdesc_rank1 obs_l_all_cfi + cdef CFI_cdesc_t *obs_l_all_ptr = &obs_l_all_cfi + cdef size_t obs_l_all_nbytes = obs_l_all.nbytes + cdef CFI_index_t obs_l_all_extent[1] + obs_l_all_extent[0] = obs_l_all.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obs_l_all_np = np.asarray(obs_l_all, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 obs_f_all_cfi + cdef CFI_cdesc_t *obs_f_all_ptr = &obs_f_all_cfi + cdef size_t obs_f_all_nbytes = obs_f_all.nbytes + cdef CFI_index_t obs_f_all_extent[1] + obs_f_all_extent[0] = obs_f_all.shape[0] + with nogil: + CFI_establish(obs_f_all_ptr, &obs_f_all[0], CFI_attribute_other, + CFI_type_double , obs_f_all_nbytes, 1, obs_f_all_extent) + + CFI_establish(obs_l_all_ptr, &obs_l_all[0], CFI_attribute_other, + CFI_type_double , obs_l_all_nbytes, 1, obs_l_all_extent) + + c__pdafomi_g2l_obs(&i_obs, obs_f_all_ptr, obs_l_all_ptr) + + return obs_l_all_np + + +def init_obs_l(int i_obs, double [::1] obs_l_all): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + obs_l_all : ndarray[np.float64, ndim=1] + Local observation vector for all variables + Array shape: (:) + + Returns + ------- + obs_l_all : ndarray[np.float64, ndim=1] + Local observation vector for all variables + Array shape: (:) + """ + cdef CFI_cdesc_rank1 obs_l_all_cfi + cdef CFI_cdesc_t *obs_l_all_ptr = &obs_l_all_cfi + cdef size_t obs_l_all_nbytes = obs_l_all.nbytes + cdef CFI_index_t obs_l_all_extent[1] + obs_l_all_extent[0] = obs_l_all.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obs_l_all_np = np.asarray(obs_l_all, dtype=np.float64, order="F") + with nogil: + CFI_establish(obs_l_all_ptr, &obs_l_all[0], CFI_attribute_other, + CFI_type_double , obs_l_all_nbytes, 1, obs_l_all_extent) + + c__pdafomi_init_obs_l(&i_obs, obs_l_all_ptr) + + return obs_l_all_np + + +def init_obsvar_l(int i_obs, double meanvar_l, int cnt_obs_l): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + meanvar_l : double + Mean variance + cnt_obs_l : int + Observation counter + + Returns + ------- + meanvar_l : double + Mean variance + cnt_obs_l : int + Observation counter + """ + with nogil: + c__pdafomi_init_obsvar_l(&i_obs, &meanvar_l, &cnt_obs_l) + + return meanvar_l, cnt_obs_l + + +def prodrinva_l(int i_obs, int nobs_all, int ncols, double [::1,:] a_l, + double [::1,:] c_l, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + nobs_all : int + Dimension of local obs. vector (all obs. types) + ncols : int + Rank of initial covariance matrix + a_l : ndarray[np.float64, ndim=2] + Input matrix (thisobs_l%dim_obs_l, ncols) + Array shape: (:, :) + c_l : ndarray[np.float64, ndim=2] + Output matrix (thisobs_l%dim_obs_l, ncols) + Array shape: (:, :) + verbose : int + Verbosity flag + + Returns + ------- + a_l : ndarray[np.float64, ndim=2] + Input matrix (thisobs_l%dim_obs_l, ncols) + Array shape: (:, :) + c_l : ndarray[np.float64, ndim=2] + Output matrix (thisobs_l%dim_obs_l, ncols) + Array shape: (:, :) + """ + cdef CFI_cdesc_rank2 a_l_cfi + cdef CFI_cdesc_t *a_l_ptr = &a_l_cfi + cdef size_t a_l_nbytes = a_l.nbytes + cdef CFI_index_t a_l_extent[2] + a_l_extent[0] = a_l.shape[0] + a_l_extent[1] = a_l.shape[1] + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] a_l_np = np.asarray(a_l, dtype=np.float64, order="F") + cdef CFI_cdesc_rank2 c_l_cfi + cdef CFI_cdesc_t *c_l_ptr = &c_l_cfi + cdef size_t c_l_nbytes = c_l.nbytes + cdef CFI_index_t c_l_extent[2] + c_l_extent[0] = c_l.shape[0] + c_l_extent[1] = c_l.shape[1] + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] c_l_np = np.asarray(c_l, dtype=np.float64, order="F") + with nogil: + CFI_establish(a_l_ptr, &a_l[0,0], CFI_attribute_other, + CFI_type_double , a_l_nbytes, 2, a_l_extent) + + CFI_establish(c_l_ptr, &c_l[0,0], CFI_attribute_other, + CFI_type_double , c_l_nbytes, 2, c_l_extent) + + c__pdafomi_prodrinva_l(&i_obs, &nobs_all, &ncols, a_l_ptr, c_l_ptr, + &verbose) + + return a_l_np, c_l_np + + +def prodrinva_hyb_l(int i_obs, int nobs_all, int ncols, double gamma, + double [::1,:] a_l, double [::1,:] c_l, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + nobs_all : int + Dimension of local obs. vector (all obs. types) + ncols : int + Rank of initial covariance matrix + gamma : double + Hybrid weight + a_l : ndarray[np.float64, ndim=2] + Input matrix (thisobs_l%dim_obs_l, ncols) + Array shape: (:, :) + c_l : ndarray[np.float64, ndim=2] + Output matrix (thisobs_l%dim_obs_l, ncols) + Array shape: (:, :) + verbose : int + Verbosity flag + + Returns + ------- + a_l : ndarray[np.float64, ndim=2] + Input matrix (thisobs_l%dim_obs_l, ncols) + Array shape: (:, :) + c_l : ndarray[np.float64, ndim=2] + Output matrix (thisobs_l%dim_obs_l, ncols) + Array shape: (:, :) + """ + cdef CFI_cdesc_rank2 a_l_cfi + cdef CFI_cdesc_t *a_l_ptr = &a_l_cfi + cdef size_t a_l_nbytes = a_l.nbytes + cdef CFI_index_t a_l_extent[2] + a_l_extent[0] = a_l.shape[0] + a_l_extent[1] = a_l.shape[1] + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] a_l_np = np.asarray(a_l, dtype=np.float64, order="F") + cdef CFI_cdesc_rank2 c_l_cfi + cdef CFI_cdesc_t *c_l_ptr = &c_l_cfi + cdef size_t c_l_nbytes = c_l.nbytes + cdef CFI_index_t c_l_extent[2] + c_l_extent[0] = c_l.shape[0] + c_l_extent[1] = c_l.shape[1] + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] c_l_np = np.asarray(c_l, dtype=np.float64, order="F") + with nogil: + CFI_establish(a_l_ptr, &a_l[0,0], CFI_attribute_other, + CFI_type_double , a_l_nbytes, 2, a_l_extent) + + CFI_establish(c_l_ptr, &c_l[0,0], CFI_attribute_other, + CFI_type_double , c_l_nbytes, 2, c_l_extent) + + c__pdafomi_prodrinva_hyb_l(&i_obs, &nobs_all, &ncols, &gamma, + a_l_ptr, c_l_ptr, &verbose) + + return a_l_np, c_l_np + + +def likelihood_l(int i_obs, double [::1] resid_l_all, double lhood_l, + int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + resid_l_all : ndarray[np.float64, ndim=1] + Input vector of residuum + Array shape: (:) + lhood_l : double + Output vector - log likelihood + verbose : int + Verbosity flag + + Returns + ------- + resid_l_all : ndarray[np.float64, ndim=1] + Input vector of residuum + Array shape: (:) + lhood_l : double + Output vector - log likelihood + """ + cdef CFI_cdesc_rank1 resid_l_all_cfi + cdef CFI_cdesc_t *resid_l_all_ptr = &resid_l_all_cfi + cdef size_t resid_l_all_nbytes = resid_l_all.nbytes + cdef CFI_index_t resid_l_all_extent[1] + resid_l_all_extent[0] = resid_l_all.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] resid_l_all_np = np.asarray(resid_l_all, dtype=np.float64, order="F") + with nogil: + CFI_establish(resid_l_all_ptr, &resid_l_all[0], CFI_attribute_other, + CFI_type_double , resid_l_all_nbytes, 1, resid_l_all_extent) + + c__pdafomi_likelihood_l(&i_obs, resid_l_all_ptr, &lhood_l, &verbose) + + return resid_l_all_np, lhood_l + + +def likelihood_hyb_l(int i_obs, double [::1] resid_l_all, double gamma, + double lhood_l, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + resid_l_all : ndarray[np.float64, ndim=1] + Input vector of residuum + Array shape: (:) + gamma : double + Hybrid weight + lhood_l : double + Output vector - log likelihood + verbose : int + Verbosity flag + + Returns + ------- + resid_l_all : ndarray[np.float64, ndim=1] + Input vector of residuum + Array shape: (:) + lhood_l : double + Output vector - log likelihood + """ + cdef CFI_cdesc_rank1 resid_l_all_cfi + cdef CFI_cdesc_t *resid_l_all_ptr = &resid_l_all_cfi + cdef size_t resid_l_all_nbytes = resid_l_all.nbytes + cdef CFI_index_t resid_l_all_extent[1] + resid_l_all_extent[0] = resid_l_all.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] resid_l_all_np = np.asarray(resid_l_all, dtype=np.float64, order="F") + with nogil: + CFI_establish(resid_l_all_ptr, &resid_l_all[0], CFI_attribute_other, + CFI_type_double , resid_l_all_nbytes, 1, resid_l_all_extent) + + c__pdafomi_likelihood_hyb_l(&i_obs, resid_l_all_ptr, &gamma, + &lhood_l, &verbose) + + return resid_l_all_np, lhood_l + + +def g2l_obs_internal(int i_obs, double [::1] obs_f_one, + int offset_obs_l_all, double [::1] obs_l_all): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + obs_f_one : ndarray[np.float64, ndim=1] + Full obs. vector of current obs. type (nobs_f_one) + Array shape: (:) + offset_obs_l_all : int + Offset of current observation in obs_l_all and ivar_l_all + obs_l_all : ndarray[np.float64, ndim=1] + Local observation vector for all variables (nobs_l_all) + Array shape: (:) + + Returns + ------- + obs_l_all : ndarray[np.float64, ndim=1] + Local observation vector for all variables (nobs_l_all) + Array shape: (:) + """ + cdef CFI_cdesc_rank1 obs_l_all_cfi + cdef CFI_cdesc_t *obs_l_all_ptr = &obs_l_all_cfi + cdef size_t obs_l_all_nbytes = obs_l_all.nbytes + cdef CFI_index_t obs_l_all_extent[1] + obs_l_all_extent[0] = obs_l_all.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obs_l_all_np = np.asarray(obs_l_all, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 obs_f_one_cfi + cdef CFI_cdesc_t *obs_f_one_ptr = &obs_f_one_cfi + cdef size_t obs_f_one_nbytes = obs_f_one.nbytes + cdef CFI_index_t obs_f_one_extent[1] + obs_f_one_extent[0] = obs_f_one.shape[0] + with nogil: + CFI_establish(obs_f_one_ptr, &obs_f_one[0], CFI_attribute_other, + CFI_type_double , obs_f_one_nbytes, 1, obs_f_one_extent) + + CFI_establish(obs_l_all_ptr, &obs_l_all[0], CFI_attribute_other, + CFI_type_double , obs_l_all_nbytes, 1, obs_l_all_extent) + + c__pdafomi_g2l_obs_internal(&i_obs, obs_f_one_ptr, + &offset_obs_l_all, obs_l_all_ptr) + + return obs_l_all_np + + +def comp_dist2(int i_obs, double [::1] coordsa, double [::1] coordsb, + int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + coordsa : ndarray[np.float64, ndim=1] + Coordinates of current analysis domain (ncoord) + Array shape: (:) + coordsb : ndarray[np.float64, ndim=1] + Coordinates of observation (ncoord) + Array shape: (:) + verbose : int + Control screen output + + Returns + ------- + distance2 : double + Squared distance + """ + cdef CFI_cdesc_rank1 coordsa_cfi + cdef CFI_cdesc_t *coordsa_ptr = &coordsa_cfi + cdef size_t coordsa_nbytes = coordsa.nbytes + cdef CFI_index_t coordsa_extent[1] + coordsa_extent[0] = coordsa.shape[0] + cdef CFI_cdesc_rank1 coordsb_cfi + cdef CFI_cdesc_t *coordsb_ptr = &coordsb_cfi + cdef size_t coordsb_nbytes = coordsb.nbytes + cdef CFI_index_t coordsb_extent[1] + coordsb_extent[0] = coordsb.shape[0] + cdef double distance2 + with nogil: + CFI_establish(coordsa_ptr, &coordsa[0], CFI_attribute_other, + CFI_type_double , coordsa_nbytes, 1, coordsa_extent) + + CFI_establish(coordsb_ptr, &coordsb[0], CFI_attribute_other, + CFI_type_double , coordsb_nbytes, 1, coordsb_extent) + + c__pdafomi_comp_dist2(&i_obs, coordsa_ptr, coordsb_ptr, &distance2, + &verbose) + + return distance2 + + +def check_dist2(int i_obs, double [::1] coordsa, double [::1] coordsb, + int verbose, int cnt_obs): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + coordsa : ndarray[np.float64, ndim=1] + Coordinates of current analysis domain (ncoord) + Array shape: (:) + coordsb : ndarray[np.float64, ndim=1] + Coordinates of observation (ncoord) + Array shape: (:) + verbose : int + Control screen output + cnt_obs : int + Count number of local observations + + Returns + ------- + distance2 : double + Squared distance + checkdist : bint + Flag whether distance is within cut-off radius + cnt_obs : int + Count number of local observations + """ + cdef CFI_cdesc_rank1 coordsa_cfi + cdef CFI_cdesc_t *coordsa_ptr = &coordsa_cfi + cdef size_t coordsa_nbytes = coordsa.nbytes + cdef CFI_index_t coordsa_extent[1] + coordsa_extent[0] = coordsa.shape[0] + cdef CFI_cdesc_rank1 coordsb_cfi + cdef CFI_cdesc_t *coordsb_ptr = &coordsb_cfi + cdef size_t coordsb_nbytes = coordsb.nbytes + cdef CFI_index_t coordsb_extent[1] + coordsb_extent[0] = coordsb.shape[0] + cdef double distance2 + cdef bint checkdist + with nogil: + CFI_establish(coordsa_ptr, &coordsa[0], CFI_attribute_other, + CFI_type_double , coordsa_nbytes, 1, coordsa_extent) + + CFI_establish(coordsb_ptr, &coordsb[0], CFI_attribute_other, + CFI_type_double , coordsb_nbytes, 1, coordsb_extent) + + c__pdafomi_check_dist2(&i_obs, coordsa_ptr, coordsb_ptr, + &distance2, &checkdist, &verbose, &cnt_obs) + + return distance2, checkdist, cnt_obs + + +def check_dist2_noniso(int i_obs, double [::1] coordsa, + double [::1] coordsb, double [::1] dists, double sradius, + int verbose, int cnt_obs): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + coordsa : ndarray[np.float64, ndim=1] + Coordinates of current analysis domain (ncoord) + Array shape: (:) + coordsb : ndarray[np.float64, ndim=1] + Coordinates of observation (ncoord) + Array shape: (:) + dists : ndarray[np.float64, ndim=1] + Vector of distance in each coordinate direction + Array shape: (:) + sradius : double + Directional support radius + verbose : int + Control screen output + cnt_obs : int + Count number of local observations + + Returns + ------- + distance2 : double + Squared distance + dists : ndarray[np.float64, ndim=1] + Vector of distance in each coordinate direction + Array shape: (:) + cradius : double + Directional cut-off radius + sradius : double + Directional support radius + checkdist : bint + Flag whether distance is within cut-off radius + cnt_obs : int + Count number of local observations + """ + cdef CFI_cdesc_rank1 dists_cfi + cdef CFI_cdesc_t *dists_ptr = &dists_cfi + cdef size_t dists_nbytes = dists.nbytes + cdef CFI_index_t dists_extent[1] + dists_extent[0] = dists.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] dists_np = np.asarray(dists, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 coordsa_cfi + cdef CFI_cdesc_t *coordsa_ptr = &coordsa_cfi + cdef size_t coordsa_nbytes = coordsa.nbytes + cdef CFI_index_t coordsa_extent[1] + coordsa_extent[0] = coordsa.shape[0] + cdef CFI_cdesc_rank1 coordsb_cfi + cdef CFI_cdesc_t *coordsb_ptr = &coordsb_cfi + cdef size_t coordsb_nbytes = coordsb.nbytes + cdef CFI_index_t coordsb_extent[1] + coordsb_extent[0] = coordsb.shape[0] + cdef double distance2 + cdef double cradius + cdef bint checkdist + with nogil: + CFI_establish(coordsa_ptr, &coordsa[0], CFI_attribute_other, + CFI_type_double , coordsa_nbytes, 1, coordsa_extent) + + CFI_establish(coordsb_ptr, &coordsb[0], CFI_attribute_other, + CFI_type_double , coordsb_nbytes, 1, coordsb_extent) + + CFI_establish(dists_ptr, &dists[0], CFI_attribute_other, + CFI_type_double , dists_nbytes, 1, dists_extent) + + c__pdafomi_check_dist2_noniso(&i_obs, coordsa_ptr, coordsb_ptr, + &distance2, dists_ptr, &cradius, + &sradius, &checkdist, &verbose, &cnt_obs) + + return distance2, dists_np, cradius, sradius, checkdist, cnt_obs + + +def weights_l(int verbose, int nobs_l, int ncols, int locweight, + double [::1] cradius, double [::1] sradius, double [::1,:] mata, + double [::1] ivar_obs_l, double [::1] dist_l, double [::1] weight_l): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + verbose : int + Verbosity flag + nobs_l : int + Number of local observations + ncols : int + + locweight : int + Localization weight type + cradius : ndarray[np.float64, ndim=1] + Localization cut-off radius + Array shape: (:) + sradius : ndarray[np.float64, ndim=1] + support radius for weight functions + Array shape: (:) + mata : ndarray[np.float64, ndim=2] + + Array shape: (:,:) + ivar_obs_l : ndarray[np.float64, ndim=1] + Local vector of inverse obs. variances (nobs_l) + Array shape: (:) + dist_l : ndarray[np.float64, ndim=1] + Local vector of obs. distances (nobs_l) + Array shape: (:) + weight_l : ndarray[np.float64, ndim=1] + Output: vector of weights + Array shape: (:) + + Returns + ------- + weight_l : ndarray[np.float64, ndim=1] + Output: vector of weights + Array shape: (:) + """ + cdef CFI_cdesc_rank1 weight_l_cfi + cdef CFI_cdesc_t *weight_l_ptr = &weight_l_cfi + cdef size_t weight_l_nbytes = weight_l.nbytes + cdef CFI_index_t weight_l_extent[1] + weight_l_extent[0] = weight_l.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] weight_l_np = np.asarray(weight_l, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 cradius_cfi + cdef CFI_cdesc_t *cradius_ptr = &cradius_cfi + cdef size_t cradius_nbytes = cradius.nbytes + cdef CFI_index_t cradius_extent[1] + cradius_extent[0] = cradius.shape[0] + cdef CFI_cdesc_rank1 sradius_cfi + cdef CFI_cdesc_t *sradius_ptr = &sradius_cfi + cdef size_t sradius_nbytes = sradius.nbytes + cdef CFI_index_t sradius_extent[1] + sradius_extent[0] = sradius.shape[0] + cdef CFI_cdesc_rank2 mata_cfi + cdef CFI_cdesc_t *mata_ptr = &mata_cfi + cdef size_t mata_nbytes = mata.nbytes + cdef CFI_index_t mata_extent[2] + mata_extent[0] = mata.shape[0] + mata_extent[1] = mata.shape[1] + cdef CFI_cdesc_rank1 ivar_obs_l_cfi + cdef CFI_cdesc_t *ivar_obs_l_ptr = &ivar_obs_l_cfi + cdef size_t ivar_obs_l_nbytes = ivar_obs_l.nbytes + cdef CFI_index_t ivar_obs_l_extent[1] + ivar_obs_l_extent[0] = ivar_obs_l.shape[0] + cdef CFI_cdesc_rank1 dist_l_cfi + cdef CFI_cdesc_t *dist_l_ptr = &dist_l_cfi + cdef size_t dist_l_nbytes = dist_l.nbytes + cdef CFI_index_t dist_l_extent[1] + dist_l_extent[0] = dist_l.shape[0] + with nogil: + CFI_establish(cradius_ptr, &cradius[0], CFI_attribute_other, + CFI_type_double , cradius_nbytes, 1, cradius_extent) + + CFI_establish(sradius_ptr, &sradius[0], CFI_attribute_other, + CFI_type_double , sradius_nbytes, 1, sradius_extent) + + CFI_establish(mata_ptr, &mata[0,0], CFI_attribute_other, + CFI_type_double , mata_nbytes, 2, mata_extent) + + CFI_establish(ivar_obs_l_ptr, &ivar_obs_l[0], CFI_attribute_other, + CFI_type_double , ivar_obs_l_nbytes, 1, ivar_obs_l_extent) + + CFI_establish(dist_l_ptr, &dist_l[0], CFI_attribute_other, + CFI_type_double , dist_l_nbytes, 1, dist_l_extent) + + CFI_establish(weight_l_ptr, &weight_l[0], CFI_attribute_other, + CFI_type_double , weight_l_nbytes, 1, weight_l_extent) + + c__pdafomi_weights_l(&verbose, &nobs_l, &ncols, &locweight, + cradius_ptr, sradius_ptr, mata_ptr, + ivar_obs_l_ptr, dist_l_ptr, weight_l_ptr) + + return weight_l_np + + +def weights_l_sgnl(int verbose, int nobs_l, int ncols, int locweight, + double cradius, double sradius, double [::1,:] mata, + double [::1] ivar_obs_l, double [::1] dist_l, double [::1] weight_l): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + verbose : int + Verbosity flag + nobs_l : int + Number of local observations + ncols : int + + locweight : int + Localization weight type + cradius : double + Localization cut-off radius + sradius : double + support radius for weight functions + mata : ndarray[np.float64, ndim=2] + + Array shape: (:,:) + ivar_obs_l : ndarray[np.float64, ndim=1] + Local vector of inverse obs. variances (nobs_l) + Array shape: (:) + dist_l : ndarray[np.float64, ndim=1] + Local vector of obs. distances (nobs_l) + Array shape: (:) + weight_l : ndarray[np.float64, ndim=1] + Output: vector of weights + Array shape: (:) + + Returns + ------- + weight_l : ndarray[np.float64, ndim=1] + Output: vector of weights + Array shape: (:) + """ + cdef CFI_cdesc_rank1 weight_l_cfi + cdef CFI_cdesc_t *weight_l_ptr = &weight_l_cfi + cdef size_t weight_l_nbytes = weight_l.nbytes + cdef CFI_index_t weight_l_extent[1] + weight_l_extent[0] = weight_l.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] weight_l_np = np.asarray(weight_l, dtype=np.float64, order="F") + cdef CFI_cdesc_rank2 mata_cfi + cdef CFI_cdesc_t *mata_ptr = &mata_cfi + cdef size_t mata_nbytes = mata.nbytes + cdef CFI_index_t mata_extent[2] + mata_extent[0] = mata.shape[0] + mata_extent[1] = mata.shape[1] + cdef CFI_cdesc_rank1 ivar_obs_l_cfi + cdef CFI_cdesc_t *ivar_obs_l_ptr = &ivar_obs_l_cfi + cdef size_t ivar_obs_l_nbytes = ivar_obs_l.nbytes + cdef CFI_index_t ivar_obs_l_extent[1] + ivar_obs_l_extent[0] = ivar_obs_l.shape[0] + cdef CFI_cdesc_rank1 dist_l_cfi + cdef CFI_cdesc_t *dist_l_ptr = &dist_l_cfi + cdef size_t dist_l_nbytes = dist_l.nbytes + cdef CFI_index_t dist_l_extent[1] + dist_l_extent[0] = dist_l.shape[0] + with nogil: + CFI_establish(mata_ptr, &mata[0,0], CFI_attribute_other, + CFI_type_double , mata_nbytes, 2, mata_extent) + + CFI_establish(ivar_obs_l_ptr, &ivar_obs_l[0], CFI_attribute_other, + CFI_type_double , ivar_obs_l_nbytes, 1, ivar_obs_l_extent) + + CFI_establish(dist_l_ptr, &dist_l[0], CFI_attribute_other, + CFI_type_double , dist_l_nbytes, 1, dist_l_extent) + + CFI_establish(weight_l_ptr, &weight_l[0], CFI_attribute_other, + CFI_type_double , weight_l_nbytes, 1, weight_l_extent) + + c__pdafomi_weights_l_sgnl(&verbose, &nobs_l, &ncols, &locweight, + &cradius, &sradius, mata_ptr, + ivar_obs_l_ptr, dist_l_ptr, weight_l_ptr) + + return weight_l_np + + +def omit_by_inno_l(int i_obs, double [::1] inno_l, + double [::1] obs_l_all, int obsid, int cnt_all, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + inno_l : ndarray[np.float64, ndim=1] + Input vector of observation innovation + Array shape: (:) + obs_l_all : ndarray[np.float64, ndim=1] + Input vector of local observations + Array shape: (:) + obsid : int + ID of observation type + cnt_all : int + Count of omitted observation over all types + verbose : int + Verbosity flag + + Returns + ------- + cnt_all : int + Count of omitted observation over all types + """ + cdef CFI_cdesc_rank1 inno_l_cfi + cdef CFI_cdesc_t *inno_l_ptr = &inno_l_cfi + cdef size_t inno_l_nbytes = inno_l.nbytes + cdef CFI_index_t inno_l_extent[1] + inno_l_extent[0] = inno_l.shape[0] + cdef CFI_cdesc_rank1 obs_l_all_cfi + cdef CFI_cdesc_t *obs_l_all_ptr = &obs_l_all_cfi + cdef size_t obs_l_all_nbytes = obs_l_all.nbytes + cdef CFI_index_t obs_l_all_extent[1] + obs_l_all_extent[0] = obs_l_all.shape[0] + with nogil: + CFI_establish(inno_l_ptr, &inno_l[0], CFI_attribute_other, + CFI_type_double , inno_l_nbytes, 1, inno_l_extent) + + CFI_establish(obs_l_all_ptr, &obs_l_all[0], CFI_attribute_other, + CFI_type_double , obs_l_all_nbytes, 1, obs_l_all_extent) + + c__pdafomi_omit_by_inno_l(&i_obs, inno_l_ptr, obs_l_all_ptr, + &obsid, &cnt_all, &verbose) + + return cnt_all + + +def obsstats_l(int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + screen : int + Verbosity flag + + Returns + ------- + """ + with nogil: + c__pdafomi_obsstats_l(&screen) + + + +def dealloc(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdafomi_dealloc() + + + +def ocoord_all(int ncoord, double [::1,:] oc_all): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + ncoord : int + Number of coordinate directions + oc_all : ndarray[np.float64, ndim=2] + Array of observation coordinates size(ncoord, dim_obs) + Array shape: (:,:) + + Returns + ------- + oc_all : ndarray[np.float64, ndim=2] + Array of observation coordinates size(ncoord, dim_obs) + Array shape: (:,:) + """ + cdef CFI_cdesc_rank2 oc_all_cfi + cdef CFI_cdesc_t *oc_all_ptr = &oc_all_cfi + cdef size_t oc_all_nbytes = oc_all.nbytes + cdef CFI_index_t oc_all_extent[2] + oc_all_extent[0] = oc_all.shape[0] + oc_all_extent[1] = oc_all.shape[1] + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] oc_all_np = np.asarray(oc_all, dtype=np.float64, order="F") + with nogil: + CFI_establish(oc_all_ptr, &oc_all[0,0], CFI_attribute_other, + CFI_type_double , oc_all_nbytes, 2, oc_all_extent) + + c__pdafomi_ocoord_all(&ncoord, oc_all_ptr) + + return oc_all_np + + +def local_weight(int wtype, int rtype, double cradius, double sradius, + double distance, int nrows, int ncols, double [::1,:] a, + double var_obs, int verbose): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + wtype : int + Type of weight function + rtype : int + Type of regulated weighting + cradius : double + Cut-off radius + sradius : double + Support radius + distance : double + Distance to observation + nrows : int + Number of rows in matrix A + ncols : int + Number of columns in matrix A + a : ndarray[np.float64, ndim=2] + Input matrix + Array shape: (nrows, ncols) + var_obs : double + Observation variance + verbose : int + Verbosity flag + + Returns + ------- + weight : double + Weights + """ + cdef double weight + with nogil: + c__pdafomi_local_weight(&wtype, &rtype, &cradius, &sradius, + &distance, &nrows, &ncols, &a[0,0], + &var_obs, &weight, &verbose) + + return weight + + +def check_dist2_loop(int i_obs, double [::1] coordsa, int cnt_obs, + int mode): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + coordsa : ndarray[np.float64, ndim=1] + Coordinates of current analysis domain (ncoord) + Array shape: (:) + cnt_obs : int + Count number of local observations + mode : int + 1: count local observations + + Returns + ------- + cnt_obs : int + Count number of local observations + """ + cdef CFI_cdesc_rank1 coordsa_cfi + cdef CFI_cdesc_t *coordsa_ptr = &coordsa_cfi + cdef size_t coordsa_nbytes = coordsa.nbytes + cdef CFI_index_t coordsa_extent[1] + coordsa_extent[0] = coordsa.shape[0] + with nogil: + CFI_establish(coordsa_ptr, &coordsa[0], CFI_attribute_other, + CFI_type_double , coordsa_nbytes, 1, coordsa_extent) + + c__pdafomi_check_dist2_loop(&i_obs, coordsa_ptr, &cnt_obs, &mode) + + return cnt_obs + + +def check_dist2_noniso_loop(int i_obs, double [::1] coordsa, + int cnt_obs, int mode): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + coordsa : ndarray[np.float64, ndim=1] + Coordinates of current analysis domain (ncoord) + Array shape: (:) + cnt_obs : int + Count number of local observations + mode : int + 1: count local observations + + Returns + ------- + cnt_obs : int + Count number of local observations + """ + cdef CFI_cdesc_rank1 coordsa_cfi + cdef CFI_cdesc_t *coordsa_ptr = &coordsa_cfi + cdef size_t coordsa_nbytes = coordsa.nbytes + cdef CFI_index_t coordsa_extent[1] + coordsa_extent[0] = coordsa.shape[0] + with nogil: + CFI_establish(coordsa_ptr, &coordsa[0], CFI_attribute_other, + CFI_type_double , coordsa_nbytes, 1, coordsa_extent) + + c__pdafomi_check_dist2_noniso_loop(&i_obs, coordsa_ptr, &cnt_obs, &mode) + + return cnt_obs + + +def obs_op_gatheronly(int i_obs, double [::1] state_p, + double [::1] obs_f_all): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + state_p : ndarray[np.float64, ndim=1] + PE-local model state (dim_p) + Array shape: (:) + obs_f_all : ndarray[np.float64, ndim=1] + Full observed state for all observation types (nobs_f_all) + Array shape: (:) + + Returns + ------- + obs_f_all : ndarray[np.float64, ndim=1] + Full observed state for all observation types (nobs_f_all) + Array shape: (:) + """ + cdef CFI_cdesc_rank1 obs_f_all_cfi + cdef CFI_cdesc_t *obs_f_all_ptr = &obs_f_all_cfi + cdef size_t obs_f_all_nbytes = obs_f_all.nbytes + cdef CFI_index_t obs_f_all_extent[1] + obs_f_all_extent[0] = obs_f_all.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obs_f_all_np = np.asarray(obs_f_all, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 state_p_cfi + cdef CFI_cdesc_t *state_p_ptr = &state_p_cfi + cdef size_t state_p_nbytes = state_p.nbytes + cdef CFI_index_t state_p_extent[1] + state_p_extent[0] = state_p.shape[0] + with nogil: + CFI_establish(state_p_ptr, &state_p[0], CFI_attribute_other, + CFI_type_double , state_p_nbytes, 1, state_p_extent) + + CFI_establish(obs_f_all_ptr, &obs_f_all[0], CFI_attribute_other, + CFI_type_double , obs_f_all_nbytes, 1, obs_f_all_extent) + + c__pdafomi_obs_op_gatheronly(&i_obs, state_p_ptr, obs_f_all_ptr) + + return obs_f_all_np + + +def obs_op_adj_gatheronly(int i_obs, double [::1] obs_f_all, + double [::1] state_p): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + obs_f_all : ndarray[np.float64, ndim=1] + Full observed state for all observation types (nobs_f_all) + Array shape: (:) + state_p : ndarray[np.float64, ndim=1] + PE-local model state (dim_p) + Array shape: (:) + + Returns + ------- + obs_f_all : ndarray[np.float64, ndim=1] + Full observed state for all observation types (nobs_f_all) + Array shape: (:) + """ + cdef CFI_cdesc_rank1 obs_f_all_cfi + cdef CFI_cdesc_t *obs_f_all_ptr = &obs_f_all_cfi + cdef size_t obs_f_all_nbytes = obs_f_all.nbytes + cdef CFI_index_t obs_f_all_extent[1] + obs_f_all_extent[0] = obs_f_all.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obs_f_all_np = np.asarray(obs_f_all, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 state_p_cfi + cdef CFI_cdesc_t *state_p_ptr = &state_p_cfi + cdef size_t state_p_nbytes = state_p.nbytes + cdef CFI_index_t state_p_extent[1] + state_p_extent[0] = state_p.shape[0] + with nogil: + CFI_establish(obs_f_all_ptr, &obs_f_all[0], CFI_attribute_other, + CFI_type_double , obs_f_all_nbytes, 1, obs_f_all_extent) + + CFI_establish(state_p_ptr, &state_p[0], CFI_attribute_other, + CFI_type_double , state_p_nbytes, 1, state_p_extent) + + c__pdafomi_obs_op_adj_gatheronly(&i_obs, obs_f_all_ptr, state_p_ptr) + + return obs_f_all_np + + +def init_obs_f(int i_obs, int dim_obs_f, double [::1] obsstate_f, + int offset): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + dim_obs_f : int + Dimension of full observed state (all observed fields) + obsstate_f : ndarray[np.float64, ndim=1] + Full observation vector (dim_obs_f) + Array shape: (:) + offset : int + input: offset of module-type observations in obsstate_f + + Returns + ------- + obsstate_f : ndarray[np.float64, ndim=1] + Full observation vector (dim_obs_f) + Array shape: (:) + offset : int + input: offset of module-type observations in obsstate_f + """ + cdef CFI_cdesc_rank1 obsstate_f_cfi + cdef CFI_cdesc_t *obsstate_f_ptr = &obsstate_f_cfi + cdef size_t obsstate_f_nbytes = obsstate_f.nbytes + cdef CFI_index_t obsstate_f_extent[1] + obsstate_f_extent[0] = obsstate_f.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obsstate_f_np = np.asarray(obsstate_f, dtype=np.float64, order="F") + with nogil: + CFI_establish(obsstate_f_ptr, &obsstate_f[0], CFI_attribute_other, + CFI_type_double , obsstate_f_nbytes, 1, obsstate_f_extent) + + c__pdafomi_init_obs_f(&i_obs, &dim_obs_f, obsstate_f_ptr, &offset) + + return obsstate_f_np, offset + + +def init_obsvars_f(int i_obs, int dim_obs_f, double [::1] var_f, + int offset): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + dim_obs_f : int + Dimension of full observed state (all observed fields) + var_f : ndarray[np.float64, ndim=1] + Full vector of observation variances (dim_obs_f) + Array shape: (:) + offset : int + input: offset of module-type observations in obsstate_f + + Returns + ------- + var_f : ndarray[np.float64, ndim=1] + Full vector of observation variances (dim_obs_f) + Array shape: (:) + offset : int + input: offset of module-type observations in obsstate_f + """ + cdef CFI_cdesc_rank1 var_f_cfi + cdef CFI_cdesc_t *var_f_ptr = &var_f_cfi + cdef size_t var_f_nbytes = var_f.nbytes + cdef CFI_index_t var_f_extent[1] + var_f_extent[0] = var_f.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] var_f_np = np.asarray(var_f, dtype=np.float64, order="F") + with nogil: + CFI_establish(var_f_ptr, &var_f[0], CFI_attribute_other, + CFI_type_double , var_f_nbytes, 1, var_f_extent) + + c__pdafomi_init_obsvars_f(&i_obs, &dim_obs_f, var_f_ptr, &offset) + + return var_f_np, offset + + +def init_obsvar_f(int i_obs, double meanvar, int cnt_obs): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + meanvar : double + Mean variance + cnt_obs : int + Observation counter + + Returns + ------- + meanvar : double + Mean variance + cnt_obs : int + Observation counter + """ + with nogil: + c__pdafomi_init_obsvar_f(&i_obs, &meanvar, &cnt_obs) + + return meanvar, cnt_obs + + +def prodrinva(int i_obs, int ncols, double [::1,:] a_p, double [::1,:] c_p): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + ncols : int + Number of columns in A_p and C_p + a_p : ndarray[np.float64, ndim=2] + Input matrix (nobs_f, ncols) + Array shape: (:, :) + c_p : ndarray[np.float64, ndim=2] + Output matrix (nobs_f, ncols) + Array shape: (:, :) + + Returns + ------- + c_p : ndarray[np.float64, ndim=2] + Output matrix (nobs_f, ncols) + Array shape: (:, :) + """ + cdef CFI_cdesc_rank2 c_p_cfi + cdef CFI_cdesc_t *c_p_ptr = &c_p_cfi + cdef size_t c_p_nbytes = c_p.nbytes + cdef CFI_index_t c_p_extent[2] + c_p_extent[0] = c_p.shape[0] + c_p_extent[1] = c_p.shape[1] + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] c_p_np = np.asarray(c_p, dtype=np.float64, order="F") + cdef CFI_cdesc_rank2 a_p_cfi + cdef CFI_cdesc_t *a_p_ptr = &a_p_cfi + cdef size_t a_p_nbytes = a_p.nbytes + cdef CFI_index_t a_p_extent[2] + a_p_extent[0] = a_p.shape[0] + a_p_extent[1] = a_p.shape[1] + with nogil: + CFI_establish(a_p_ptr, &a_p[0,0], CFI_attribute_other, + CFI_type_double , a_p_nbytes, 2, a_p_extent) + + CFI_establish(c_p_ptr, &c_p[0,0], CFI_attribute_other, + CFI_type_double , c_p_nbytes, 2, c_p_extent) + + c__pdafomi_prodrinva(&i_obs, &ncols, a_p_ptr, c_p_ptr) + + return c_p_np + + +def likelihood(int i_obs, double [::1] resid, double lhood): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + resid : ndarray[np.float64, ndim=1] + Input vector of residuum + Array shape: (:) + lhood : double + Output vector - log likelihood + + Returns + ------- + lhood : double + Output vector - log likelihood + """ + cdef CFI_cdesc_rank1 resid_cfi + cdef CFI_cdesc_t *resid_ptr = &resid_cfi + cdef size_t resid_nbytes = resid.nbytes + cdef CFI_index_t resid_extent[1] + resid_extent[0] = resid.shape[0] + with nogil: + CFI_establish(resid_ptr, &resid[0], CFI_attribute_other, + CFI_type_double , resid_nbytes, 1, resid_extent) + + c__pdafomi_likelihood(&i_obs, resid_ptr, &lhood) + + return lhood + + +def add_obs_error(int i_obs, int nobs_all, double [::1,:] matc): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + nobs_all : int + Number of observations + matc : ndarray[np.float64, ndim=2] + Input/Output matrix (nobs_f, rank) + Array shape: (:, :) + + Returns + ------- + matc : ndarray[np.float64, ndim=2] + Input/Output matrix (nobs_f, rank) + Array shape: (:, :) + """ + cdef CFI_cdesc_rank2 matc_cfi + cdef CFI_cdesc_t *matc_ptr = &matc_cfi + cdef size_t matc_nbytes = matc.nbytes + cdef CFI_index_t matc_extent[2] + matc_extent[0] = matc.shape[0] + matc_extent[1] = matc.shape[1] + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] matc_np = np.asarray(matc, dtype=np.float64, order="F") + with nogil: + CFI_establish(matc_ptr, &matc[0,0], CFI_attribute_other, + CFI_type_double , matc_nbytes, 2, matc_extent) + + c__pdafomi_add_obs_error(&i_obs, &nobs_all, matc_ptr) + + return matc_np + + +def init_obscovar(int i_obs, int nobs_all, double [::1,:] covar): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + nobs_all : int + Number of observations + covar : ndarray[np.float64, ndim=2] + Input/Output matrix (nobs_all, nobs_all) + Array shape: (:, :) + + Returns + ------- + covar : ndarray[np.float64, ndim=2] + Input/Output matrix (nobs_all, nobs_all) + Array shape: (:, :) + isdiag : bint + Whether matrix R is diagonal + """ + cdef CFI_cdesc_rank2 covar_cfi + cdef CFI_cdesc_t *covar_ptr = &covar_cfi + cdef size_t covar_nbytes = covar.nbytes + cdef CFI_index_t covar_extent[2] + covar_extent[0] = covar.shape[0] + covar_extent[1] = covar.shape[1] + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] covar_np = np.asarray(covar, dtype=np.float64, order="F") + cdef bint isdiag + with nogil: + CFI_establish(covar_ptr, &covar[0,0], CFI_attribute_other, + CFI_type_double , covar_nbytes, 2, covar_extent) + + c__pdafomi_init_obscovar(&i_obs, &nobs_all, covar_ptr, &isdiag) + + return covar_np, isdiag + + +def init_obserr_f(int i_obs, double [::1] obserr_f): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + obserr_f : ndarray[np.float64, ndim=1] + Full vector of observation errors + Array shape: (:) + + Returns + ------- + obserr_f : ndarray[np.float64, ndim=1] + Full vector of observation errors + Array shape: (:) + """ + cdef CFI_cdesc_rank1 obserr_f_cfi + cdef CFI_cdesc_t *obserr_f_ptr = &obserr_f_cfi + cdef size_t obserr_f_nbytes = obserr_f.nbytes + cdef CFI_index_t obserr_f_extent[1] + obserr_f_extent[0] = obserr_f.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obserr_f_np = np.asarray(obserr_f, dtype=np.float64, order="F") + with nogil: + CFI_establish(obserr_f_ptr, &obserr_f[0], CFI_attribute_other, + CFI_type_double , obserr_f_nbytes, 1, obserr_f_extent) + + c__pdafomi_init_obserr_f(&i_obs, obserr_f_ptr) + + return obserr_f_np + + +def get_local_ids_obs_f(int dim_obs_g, double lradius, + double [::1,:] oc_f, int [::1] id_lim, int disttype, + double [::1] domainsize): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_obs_g : int + Global full number of observations + lradius : double + Localization radius (used is a constant one here) + oc_f : ndarray[np.float64, ndim=2] + observation coordinates (radians), row 1: lon, 2: lat + Array shape: (:,:) + id_lim : ndarray[np.intc, ndim=1] + Indices of process-local full obs. in global full vector + Array shape: (:) + disttype : int + type of distance computation + domainsize : ndarray[np.float64, ndim=1] + Global size of model domain + Array shape: (:) + + Returns + ------- + cnt_lim : int + Number of full observation for local process domain + id_lim : ndarray[np.intc, ndim=1] + Indices of process-local full obs. in global full vector + Array shape: (:) + """ + cdef CFI_cdesc_rank1 id_lim_cfi + cdef CFI_cdesc_t *id_lim_ptr = &id_lim_cfi + cdef size_t id_lim_nbytes = id_lim.nbytes + cdef CFI_index_t id_lim_extent[1] + id_lim_extent[0] = id_lim.shape[0] + cdef cnp.ndarray[cnp.int32_t, ndim=1, mode="fortran", negative_indices=False, cast=False] id_lim_np = np.asarray(id_lim, dtype=np.intc, order="F") + cdef CFI_cdesc_rank2 oc_f_cfi + cdef CFI_cdesc_t *oc_f_ptr = &oc_f_cfi + cdef size_t oc_f_nbytes = oc_f.nbytes + cdef CFI_index_t oc_f_extent[2] + oc_f_extent[0] = oc_f.shape[0] + oc_f_extent[1] = oc_f.shape[1] + cdef CFI_cdesc_rank1 domainsize_cfi + cdef CFI_cdesc_t *domainsize_ptr = &domainsize_cfi + cdef size_t domainsize_nbytes = domainsize.nbytes + cdef CFI_index_t domainsize_extent[1] + domainsize_extent[0] = domainsize.shape[0] + cdef int cnt_lim + with nogil: + CFI_establish(oc_f_ptr, &oc_f[0,0], CFI_attribute_other, + CFI_type_double , oc_f_nbytes, 2, oc_f_extent) + + CFI_establish(id_lim_ptr, &id_lim[0], CFI_attribute_other, + CFI_type_int , id_lim_nbytes, 1, id_lim_extent) + + CFI_establish(domainsize_ptr, &domainsize[0], CFI_attribute_other, + CFI_type_double , domainsize_nbytes, 1, domainsize_extent) + + c__pdafomi_get_local_ids_obs_f(&dim_obs_g, &lradius, oc_f_ptr, + &cnt_lim, id_lim_ptr, &disttype, + domainsize_ptr) + + return cnt_lim, id_lim_np + + +def limit_obs_f(int i_obs, int offset, double [::1] obs_f_one, + double [::1] obs_f_lim): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + offset : int + offset of this observation in obs_f_lim + obs_f_one : ndarray[np.float64, ndim=1] + Global full observation vector (nobs_f) + Array shape: (:) + obs_f_lim : ndarray[np.float64, ndim=1] + full observation vector for process domains (nobs_lim) + Array shape: (:) + + Returns + ------- + obs_f_lim : ndarray[np.float64, ndim=1] + full observation vector for process domains (nobs_lim) + Array shape: (:) + """ + cdef CFI_cdesc_rank1 obs_f_lim_cfi + cdef CFI_cdesc_t *obs_f_lim_ptr = &obs_f_lim_cfi + cdef size_t obs_f_lim_nbytes = obs_f_lim.nbytes + cdef CFI_index_t obs_f_lim_extent[1] + obs_f_lim_extent[0] = obs_f_lim.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obs_f_lim_np = np.asarray(obs_f_lim, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 obs_f_one_cfi + cdef CFI_cdesc_t *obs_f_one_ptr = &obs_f_one_cfi + cdef size_t obs_f_one_nbytes = obs_f_one.nbytes + cdef CFI_index_t obs_f_one_extent[1] + obs_f_one_extent[0] = obs_f_one.shape[0] + with nogil: + CFI_establish(obs_f_one_ptr, &obs_f_one[0], CFI_attribute_other, + CFI_type_double , obs_f_one_nbytes, 1, obs_f_one_extent) + + CFI_establish(obs_f_lim_ptr, &obs_f_lim[0], CFI_attribute_other, + CFI_type_double , obs_f_lim_nbytes, 1, obs_f_lim_extent) + + c__pdafomi_limit_obs_f(&i_obs, &offset, obs_f_one_ptr, obs_f_lim_ptr) + + return obs_f_lim_np + + +def gather_dim_obs_f(int dim_obs_p): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_obs_p : int + PE-local observation dimension + + Returns + ------- + dim_obs_f : int + Full observation dimension + """ + cdef int dim_obs_f + with nogil: + c__pdafomi_gather_dim_obs_f(&dim_obs_p, &dim_obs_f) + + return dim_obs_f + + +def gather_obs_f_flex(int dim_obs_p, double [::1] obs_p, double [::1] obs_f): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_obs_p : int + PE-local observation dimension + obs_p : ndarray[np.float64, ndim=1] + PE-local vector + Array shape: (:) + obs_f : ndarray[np.float64, ndim=1] + Full gathered vector + Array shape: (:) + + Returns + ------- + obs_f : ndarray[np.float64, ndim=1] + Full gathered vector + Array shape: (:) + status : int + Status flag: (0) no error + """ + cdef CFI_cdesc_rank1 obs_f_cfi + cdef CFI_cdesc_t *obs_f_ptr = &obs_f_cfi + cdef size_t obs_f_nbytes = obs_f.nbytes + cdef CFI_index_t obs_f_extent[1] + obs_f_extent[0] = obs_f.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] obs_f_np = np.asarray(obs_f, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 obs_p_cfi + cdef CFI_cdesc_t *obs_p_ptr = &obs_p_cfi + cdef size_t obs_p_nbytes = obs_p.nbytes + cdef CFI_index_t obs_p_extent[1] + obs_p_extent[0] = obs_p.shape[0] + cdef int status + with nogil: + CFI_establish(obs_p_ptr, &obs_p[0], CFI_attribute_other, + CFI_type_double , obs_p_nbytes, 1, obs_p_extent) + + CFI_establish(obs_f_ptr, &obs_f[0], CFI_attribute_other, + CFI_type_double , obs_f_nbytes, 1, obs_f_extent) + + c__pdafomi_gather_obs_f_flex(&dim_obs_p, obs_p_ptr, obs_f_ptr, &status) + + return obs_f_np, status + + +def gather_obs_f2_flex(int dim_obs_p, double [::1,:] coords_p, + double [::1,:] coords_f, int nrows): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + dim_obs_p : int + PE-local observation dimension + coords_p : ndarray[np.float64, ndim=2] + PE-local array + Array shape: (:,:) + coords_f : ndarray[np.float64, ndim=2] + Full gathered array + Array shape: (:,:) + nrows : int + Number of rows in array + + Returns + ------- + coords_f : ndarray[np.float64, ndim=2] + Full gathered array + Array shape: (:,:) + status : int + Status flag: (0) no error + """ + cdef CFI_cdesc_rank2 coords_f_cfi + cdef CFI_cdesc_t *coords_f_ptr = &coords_f_cfi + cdef size_t coords_f_nbytes = coords_f.nbytes + cdef CFI_index_t coords_f_extent[2] + coords_f_extent[0] = coords_f.shape[0] + coords_f_extent[1] = coords_f.shape[1] + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] coords_f_np = np.asarray(coords_f, dtype=np.float64, order="F") + cdef CFI_cdesc_rank2 coords_p_cfi + cdef CFI_cdesc_t *coords_p_ptr = &coords_p_cfi + cdef size_t coords_p_nbytes = coords_p.nbytes + cdef CFI_index_t coords_p_extent[2] + coords_p_extent[0] = coords_p.shape[0] + coords_p_extent[1] = coords_p.shape[1] + cdef int status + with nogil: + CFI_establish(coords_p_ptr, &coords_p[0,0], CFI_attribute_other, + CFI_type_double , coords_p_nbytes, 2, coords_p_extent) + + CFI_establish(coords_f_ptr, &coords_f[0,0], CFI_attribute_other, + CFI_type_double , coords_f_nbytes, 2, coords_f_extent) + + c__pdafomi_gather_obs_f2_flex(&dim_obs_p, coords_p_ptr, + coords_f_ptr, &nrows, &status) + + return coords_f_np, status + + +def omit_by_inno(int i_obs, double [::1] inno_f, double [::1] obs_f_all, + int obsid, int cnt_all): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + inno_f : ndarray[np.float64, ndim=1] + Input vector of observation innovation + Array shape: (:) + obs_f_all : ndarray[np.float64, ndim=1] + Input vector of local observations + Array shape: (:) + obsid : int + ID of observation type + cnt_all : int + Count of omitted observation over all types + + Returns + ------- + cnt_all : int + Count of omitted observation over all types + """ + cdef CFI_cdesc_rank1 inno_f_cfi + cdef CFI_cdesc_t *inno_f_ptr = &inno_f_cfi + cdef size_t inno_f_nbytes = inno_f.nbytes + cdef CFI_index_t inno_f_extent[1] + inno_f_extent[0] = inno_f.shape[0] + cdef CFI_cdesc_rank1 obs_f_all_cfi + cdef CFI_cdesc_t *obs_f_all_ptr = &obs_f_all_cfi + cdef size_t obs_f_all_nbytes = obs_f_all.nbytes + cdef CFI_index_t obs_f_all_extent[1] + obs_f_all_extent[0] = obs_f_all.shape[0] + with nogil: + CFI_establish(inno_f_ptr, &inno_f[0], CFI_attribute_other, + CFI_type_double , inno_f_nbytes, 1, inno_f_extent) + + CFI_establish(obs_f_all_ptr, &obs_f_all[0], CFI_attribute_other, + CFI_type_double , obs_f_all_nbytes, 1, obs_f_all_extent) + + c__pdafomi_omit_by_inno(&i_obs, inno_f_ptr, obs_f_all_ptr, &obsid, + &cnt_all) + + return cnt_all + + +def obsstats(int screen): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + screen : int + Verbosity flag + + Returns + ------- + """ + with nogil: + c__pdafomi_obsstats(&screen) + + + +def gather_obsdims(): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + """ + with nogil: + c__pdafomi_gather_obsdims() + + + diff --git a/pyPDAF/source/src/pyPDAF/PDAFomi/legacy.pxd b/pyPDAF/source/src/pyPDAF/PDAFomi/legacy.pxd new file mode 100644 index 0000000000000000000000000000000000000000..ad40732a6277b9a3d5876adb5c682e2254723ffe --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFomi/legacy.pxd @@ -0,0 +1,47 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t +cdef extern void c__pdafomi_localize_covar_iso(int* i_obs, int* dim, + int* locweight, double* cradius, double* sradius, CFI_cdesc_t* coords, + CFI_cdesc_t* hp, CFI_cdesc_t* hph) noexcept nogil; + +cdef extern void c__pdafomi_localize_covar_noniso_locweights(int* i_obs, + int* dim, CFI_cdesc_t* locweights, CFI_cdesc_t* cradius, + CFI_cdesc_t* sradius, CFI_cdesc_t* coords, CFI_cdesc_t* hp, + CFI_cdesc_t* hph) noexcept nogil; + +cdef extern void c__pdafomi_localize_covar_noniso(int* i_obs, int* dim, + int* locweight, CFI_cdesc_t* cradius, CFI_cdesc_t* sradius, + CFI_cdesc_t* coords, CFI_cdesc_t* hp, + CFI_cdesc_t* hph) noexcept nogil; + +cdef extern void c__pdafomi_localize_covar_serial_iso(int* i_obs, + int* iobs_all, int* dim, int* dim_obs, int* locweight, double* cradius, + double* sradius, CFI_cdesc_t* coords, CFI_cdesc_t* hp, + CFI_cdesc_t* hxy) noexcept nogil; + +cdef extern void c__pdafomi_localize_covar_serial_noniso_locweights( + int* i_obs, int* iobs_all, int* dim, int* dim_obs, + CFI_cdesc_t* locweights, CFI_cdesc_t* cradius, CFI_cdesc_t* sradius, + CFI_cdesc_t* coords, CFI_cdesc_t* hp, + CFI_cdesc_t* hxy) noexcept nogil; + +cdef extern void c__pdafomi_localize_covar_serial_noniso(int* i_obs, + int* iobs_all, int* dim, int* dim_obs, int* locweight, + CFI_cdesc_t* cradius, CFI_cdesc_t* sradius, CFI_cdesc_t* coords, + CFI_cdesc_t* hp, CFI_cdesc_t* hxy) noexcept nogil; + +cdef extern void c__pdafomi_init_dim_obs_l_iso_old(int* i_obs, + CFI_cdesc_t* coords_l, int* locweight, double* cradius, + double* sradius, int* cnt_obs_l) noexcept nogil; + +cdef extern void c__pdafomi_init_dim_obs_l_noniso_old(int* i_obs, + CFI_cdesc_t* coords_l, int* locweight, CFI_cdesc_t* cradius, + CFI_cdesc_t* sradius, int* cnt_obs_l) noexcept nogil; + +cdef extern void c__pdafomi_init_dim_obs_l_noniso_locweights_old( + int* i_obs, CFI_cdesc_t* coords_l, CFI_cdesc_t* locweights, + CFI_cdesc_t* cradius, CFI_cdesc_t* sradius, + int* cnt_obs_l) noexcept nogil; + +cdef extern void c__pdafomi_deallocate_obs( + int* i_obs) noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/PDAFomi/legacy.pyx b/pyPDAF/source/src/pyPDAF/PDAFomi/legacy.pyx new file mode 100644 index 0000000000000000000000000000000000000000..667c7ec8fd8840612dd4edfc54d967d344413f62 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFomi/legacy.pyx @@ -0,0 +1,747 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + +def localize_covar_iso(int i_obs, int dim, int locweight, + double cradius, double sradius, double [::1,:] coords, + double [::1,:] hp, double [::1,:] hph): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + dim : int + State dimension + locweight : int + Localization weight type + cradius : double + localization radius + sradius : double + support radius for weight functions + coords : ndarray[np.float64, ndim=2] + Coordinates of state vector elements + Array shape: (:,:) + hp : ndarray[np.float64, ndim=2] + Matrix HP, dimension (nobs, dim) + Array shape: (:, :) + hph : ndarray[np.float64, ndim=2] + Matrix HPH, dimension (nobs, nobs) + Array shape: (:, :) + + Returns + ------- + hp : ndarray[np.float64, ndim=2] + Matrix HP, dimension (nobs, dim) + Array shape: (:, :) + hph : ndarray[np.float64, ndim=2] + Matrix HPH, dimension (nobs, nobs) + Array shape: (:, :) + """ + cdef CFI_cdesc_rank2 hp_cfi + cdef CFI_cdesc_t *hp_ptr = &hp_cfi + cdef size_t hp_nbytes = hp.nbytes + cdef CFI_index_t hp_extent[2] + hp_extent[0] = hp.shape[0] + hp_extent[1] = hp.shape[1] + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hp_np = np.asarray(hp, dtype=np.float64, order="F") + cdef CFI_cdesc_rank2 hph_cfi + cdef CFI_cdesc_t *hph_ptr = &hph_cfi + cdef size_t hph_nbytes = hph.nbytes + cdef CFI_index_t hph_extent[2] + hph_extent[0] = hph.shape[0] + hph_extent[1] = hph.shape[1] + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hph_np = np.asarray(hph, dtype=np.float64, order="F") + cdef CFI_cdesc_rank2 coords_cfi + cdef CFI_cdesc_t *coords_ptr = &coords_cfi + cdef size_t coords_nbytes = coords.nbytes + cdef CFI_index_t coords_extent[2] + coords_extent[0] = coords.shape[0] + coords_extent[1] = coords.shape[1] + with nogil: + CFI_establish(coords_ptr, &coords[0,0], CFI_attribute_other, + CFI_type_double , coords_nbytes, 2, coords_extent) + + CFI_establish(hp_ptr, &hp[0,0], CFI_attribute_other, + CFI_type_double , hp_nbytes, 2, hp_extent) + + CFI_establish(hph_ptr, &hph[0,0], CFI_attribute_other, + CFI_type_double , hph_nbytes, 2, hph_extent) + + c__pdafomi_localize_covar_iso(&i_obs, &dim, &locweight, &cradius, + &sradius, coords_ptr, hp_ptr, hph_ptr) + + return hp_np, hph_np + + +def localize_covar_noniso_locweights(int i_obs, int dim, + int [::1] locweights, double [::1] cradius, double [::1] sradius, + double [::1,:] coords, double [::1,:] hp, double [::1,:] hph): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + dim : int + State dimension + locweights : ndarray[np.intc, ndim=1] + Types of localization function + Array shape: (:) + cradius : ndarray[np.float64, ndim=1] + Vector of localization cut-off radii + Array shape: (:) + sradius : ndarray[np.float64, ndim=1] + Vector of support radii of localization function + Array shape: (:) + coords : ndarray[np.float64, ndim=2] + Coordinates of state vector elements + Array shape: (:,:) + hp : ndarray[np.float64, ndim=2] + Matrix HP, dimension (nobs, dim) + Array shape: (:, :) + hph : ndarray[np.float64, ndim=2] + Matrix HPH, dimension (nobs, nobs) + Array shape: (:, :) + + Returns + ------- + hp : ndarray[np.float64, ndim=2] + Matrix HP, dimension (nobs, dim) + Array shape: (:, :) + hph : ndarray[np.float64, ndim=2] + Matrix HPH, dimension (nobs, nobs) + Array shape: (:, :) + """ + cdef CFI_cdesc_rank2 hp_cfi + cdef CFI_cdesc_t *hp_ptr = &hp_cfi + cdef size_t hp_nbytes = hp.nbytes + cdef CFI_index_t hp_extent[2] + hp_extent[0] = hp.shape[0] + hp_extent[1] = hp.shape[1] + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hp_np = np.asarray(hp, dtype=np.float64, order="F") + cdef CFI_cdesc_rank2 hph_cfi + cdef CFI_cdesc_t *hph_ptr = &hph_cfi + cdef size_t hph_nbytes = hph.nbytes + cdef CFI_index_t hph_extent[2] + hph_extent[0] = hph.shape[0] + hph_extent[1] = hph.shape[1] + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hph_np = np.asarray(hph, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 locweights_cfi + cdef CFI_cdesc_t *locweights_ptr = &locweights_cfi + cdef size_t locweights_nbytes = locweights.nbytes + cdef CFI_index_t locweights_extent[1] + locweights_extent[0] = locweights.shape[0] + cdef CFI_cdesc_rank1 cradius_cfi + cdef CFI_cdesc_t *cradius_ptr = &cradius_cfi + cdef size_t cradius_nbytes = cradius.nbytes + cdef CFI_index_t cradius_extent[1] + cradius_extent[0] = cradius.shape[0] + cdef CFI_cdesc_rank1 sradius_cfi + cdef CFI_cdesc_t *sradius_ptr = &sradius_cfi + cdef size_t sradius_nbytes = sradius.nbytes + cdef CFI_index_t sradius_extent[1] + sradius_extent[0] = sradius.shape[0] + cdef CFI_cdesc_rank2 coords_cfi + cdef CFI_cdesc_t *coords_ptr = &coords_cfi + cdef size_t coords_nbytes = coords.nbytes + cdef CFI_index_t coords_extent[2] + coords_extent[0] = coords.shape[0] + coords_extent[1] = coords.shape[1] + with nogil: + CFI_establish(locweights_ptr, &locweights[0], CFI_attribute_other, + CFI_type_int , locweights_nbytes, 1, locweights_extent) + + CFI_establish(cradius_ptr, &cradius[0], CFI_attribute_other, + CFI_type_double , cradius_nbytes, 1, cradius_extent) + + CFI_establish(sradius_ptr, &sradius[0], CFI_attribute_other, + CFI_type_double , sradius_nbytes, 1, sradius_extent) + + CFI_establish(coords_ptr, &coords[0,0], CFI_attribute_other, + CFI_type_double , coords_nbytes, 2, coords_extent) + + CFI_establish(hp_ptr, &hp[0,0], CFI_attribute_other, + CFI_type_double , hp_nbytes, 2, hp_extent) + + CFI_establish(hph_ptr, &hph[0,0], CFI_attribute_other, + CFI_type_double , hph_nbytes, 2, hph_extent) + + c__pdafomi_localize_covar_noniso_locweights(&i_obs, &dim, + locweights_ptr, + cradius_ptr, + sradius_ptr, + coords_ptr, hp_ptr, hph_ptr) + + return hp_np, hph_np + + +def localize_covar_noniso(int i_obs, int dim, int locweight, + double [::1] cradius, double [::1] sradius, double [::1,:] coords, + double [::1,:] hp, double [::1,:] hph): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + dim : int + State dimension + locweight : int + Localization weight type + cradius : ndarray[np.float64, ndim=1] + Vector of localization cut-off radii + Array shape: (:) + sradius : ndarray[np.float64, ndim=1] + Vector of support radii of localization function + Array shape: (:) + coords : ndarray[np.float64, ndim=2] + Coordinates of state vector elements + Array shape: (:,:) + hp : ndarray[np.float64, ndim=2] + Matrix HP, dimension (nobs, dim) + Array shape: (:, :) + hph : ndarray[np.float64, ndim=2] + Matrix HPH, dimension (nobs, nobs) + Array shape: (:, :) + + Returns + ------- + hp : ndarray[np.float64, ndim=2] + Matrix HP, dimension (nobs, dim) + Array shape: (:, :) + hph : ndarray[np.float64, ndim=2] + Matrix HPH, dimension (nobs, nobs) + Array shape: (:, :) + """ + cdef CFI_cdesc_rank2 hp_cfi + cdef CFI_cdesc_t *hp_ptr = &hp_cfi + cdef size_t hp_nbytes = hp.nbytes + cdef CFI_index_t hp_extent[2] + hp_extent[0] = hp.shape[0] + hp_extent[1] = hp.shape[1] + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hp_np = np.asarray(hp, dtype=np.float64, order="F") + cdef CFI_cdesc_rank2 hph_cfi + cdef CFI_cdesc_t *hph_ptr = &hph_cfi + cdef size_t hph_nbytes = hph.nbytes + cdef CFI_index_t hph_extent[2] + hph_extent[0] = hph.shape[0] + hph_extent[1] = hph.shape[1] + cdef cnp.ndarray[cnp.float64_t, ndim=2, mode="fortran", negative_indices=False, cast=False] hph_np = np.asarray(hph, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 cradius_cfi + cdef CFI_cdesc_t *cradius_ptr = &cradius_cfi + cdef size_t cradius_nbytes = cradius.nbytes + cdef CFI_index_t cradius_extent[1] + cradius_extent[0] = cradius.shape[0] + cdef CFI_cdesc_rank1 sradius_cfi + cdef CFI_cdesc_t *sradius_ptr = &sradius_cfi + cdef size_t sradius_nbytes = sradius.nbytes + cdef CFI_index_t sradius_extent[1] + sradius_extent[0] = sradius.shape[0] + cdef CFI_cdesc_rank2 coords_cfi + cdef CFI_cdesc_t *coords_ptr = &coords_cfi + cdef size_t coords_nbytes = coords.nbytes + cdef CFI_index_t coords_extent[2] + coords_extent[0] = coords.shape[0] + coords_extent[1] = coords.shape[1] + with nogil: + CFI_establish(cradius_ptr, &cradius[0], CFI_attribute_other, + CFI_type_double , cradius_nbytes, 1, cradius_extent) + + CFI_establish(sradius_ptr, &sradius[0], CFI_attribute_other, + CFI_type_double , sradius_nbytes, 1, sradius_extent) + + CFI_establish(coords_ptr, &coords[0,0], CFI_attribute_other, + CFI_type_double , coords_nbytes, 2, coords_extent) + + CFI_establish(hp_ptr, &hp[0,0], CFI_attribute_other, + CFI_type_double , hp_nbytes, 2, hp_extent) + + CFI_establish(hph_ptr, &hph[0,0], CFI_attribute_other, + CFI_type_double , hph_nbytes, 2, hph_extent) + + c__pdafomi_localize_covar_noniso(&i_obs, &dim, &locweight, + cradius_ptr, sradius_ptr, + coords_ptr, hp_ptr, hph_ptr) + + return hp_np, hph_np + + +def localize_covar_serial_iso(int i_obs, int iobs_all, int dim, + int dim_obs, int locweight, double cradius, double sradius, + double [::1,:] coords, double [::1] hp, double [::1] hxy): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + iobs_all : int + Index of current observation + dim : int + State dimension + dim_obs : int + Overall full observation dimension + locweight : int + Localization weight type + cradius : double + localization radius + sradius : double + support radius for weight functions + coords : ndarray[np.float64, ndim=2] + Coordinates of state vector elements + Array shape: (:,:) + hp : ndarray[np.float64, ndim=1] + Vector HP, dimension (dim) + Array shape: (:) + hxy : ndarray[np.float64, ndim=1] + Matrix HXY, dimension (nobs) + Array shape: (:) + + Returns + ------- + hp : ndarray[np.float64, ndim=1] + Vector HP, dimension (dim) + Array shape: (:) + hxy : ndarray[np.float64, ndim=1] + Matrix HXY, dimension (nobs) + Array shape: (:) + """ + cdef CFI_cdesc_rank1 hp_cfi + cdef CFI_cdesc_t *hp_ptr = &hp_cfi + cdef size_t hp_nbytes = hp.nbytes + cdef CFI_index_t hp_extent[1] + hp_extent[0] = hp.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] hp_np = np.asarray(hp, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 hxy_cfi + cdef CFI_cdesc_t *hxy_ptr = &hxy_cfi + cdef size_t hxy_nbytes = hxy.nbytes + cdef CFI_index_t hxy_extent[1] + hxy_extent[0] = hxy.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] hxy_np = np.asarray(hxy, dtype=np.float64, order="F") + cdef CFI_cdesc_rank2 coords_cfi + cdef CFI_cdesc_t *coords_ptr = &coords_cfi + cdef size_t coords_nbytes = coords.nbytes + cdef CFI_index_t coords_extent[2] + coords_extent[0] = coords.shape[0] + coords_extent[1] = coords.shape[1] + with nogil: + CFI_establish(coords_ptr, &coords[0,0], CFI_attribute_other, + CFI_type_double , coords_nbytes, 2, coords_extent) + + CFI_establish(hp_ptr, &hp[0], CFI_attribute_other, + CFI_type_double , hp_nbytes, 1, hp_extent) + + CFI_establish(hxy_ptr, &hxy[0], CFI_attribute_other, + CFI_type_double , hxy_nbytes, 1, hxy_extent) + + c__pdafomi_localize_covar_serial_iso(&i_obs, &iobs_all, &dim, + &dim_obs, &locweight, + &cradius, &sradius, + coords_ptr, hp_ptr, hxy_ptr) + + return hp_np, hxy_np + + +def localize_covar_serial_noniso_locweights(int i_obs, int iobs_all, + int dim, int dim_obs, int [::1] locweights, double [::1] cradius, + double [::1] sradius, double [::1,:] coords, double [::1] hp, + double [::1] hxy): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + iobs_all : int + Index of current observation + dim : int + State dimension + dim_obs : int + Overall full observation dimension + locweights : ndarray[np.intc, ndim=1] + Types of localization function + Array shape: (:) + cradius : ndarray[np.float64, ndim=1] + Vector of localization cut-off radii + Array shape: (:) + sradius : ndarray[np.float64, ndim=1] + Vector of support radii of localization function + Array shape: (:) + coords : ndarray[np.float64, ndim=2] + Coordinates of state vector elements + Array shape: (:,:) + hp : ndarray[np.float64, ndim=1] + Vector HP, dimension (dim) + Array shape: (:) + hxy : ndarray[np.float64, ndim=1] + Matrix HXY, dimension (nobs) + Array shape: (:) + + Returns + ------- + hp : ndarray[np.float64, ndim=1] + Vector HP, dimension (dim) + Array shape: (:) + hxy : ndarray[np.float64, ndim=1] + Matrix HXY, dimension (nobs) + Array shape: (:) + """ + cdef CFI_cdesc_rank1 hp_cfi + cdef CFI_cdesc_t *hp_ptr = &hp_cfi + cdef size_t hp_nbytes = hp.nbytes + cdef CFI_index_t hp_extent[1] + hp_extent[0] = hp.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] hp_np = np.asarray(hp, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 hxy_cfi + cdef CFI_cdesc_t *hxy_ptr = &hxy_cfi + cdef size_t hxy_nbytes = hxy.nbytes + cdef CFI_index_t hxy_extent[1] + hxy_extent[0] = hxy.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] hxy_np = np.asarray(hxy, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 locweights_cfi + cdef CFI_cdesc_t *locweights_ptr = &locweights_cfi + cdef size_t locweights_nbytes = locweights.nbytes + cdef CFI_index_t locweights_extent[1] + locweights_extent[0] = locweights.shape[0] + cdef CFI_cdesc_rank1 cradius_cfi + cdef CFI_cdesc_t *cradius_ptr = &cradius_cfi + cdef size_t cradius_nbytes = cradius.nbytes + cdef CFI_index_t cradius_extent[1] + cradius_extent[0] = cradius.shape[0] + cdef CFI_cdesc_rank1 sradius_cfi + cdef CFI_cdesc_t *sradius_ptr = &sradius_cfi + cdef size_t sradius_nbytes = sradius.nbytes + cdef CFI_index_t sradius_extent[1] + sradius_extent[0] = sradius.shape[0] + cdef CFI_cdesc_rank2 coords_cfi + cdef CFI_cdesc_t *coords_ptr = &coords_cfi + cdef size_t coords_nbytes = coords.nbytes + cdef CFI_index_t coords_extent[2] + coords_extent[0] = coords.shape[0] + coords_extent[1] = coords.shape[1] + with nogil: + CFI_establish(locweights_ptr, &locweights[0], CFI_attribute_other, + CFI_type_int , locweights_nbytes, 1, locweights_extent) + + CFI_establish(cradius_ptr, &cradius[0], CFI_attribute_other, + CFI_type_double , cradius_nbytes, 1, cradius_extent) + + CFI_establish(sradius_ptr, &sradius[0], CFI_attribute_other, + CFI_type_double , sradius_nbytes, 1, sradius_extent) + + CFI_establish(coords_ptr, &coords[0,0], CFI_attribute_other, + CFI_type_double , coords_nbytes, 2, coords_extent) + + CFI_establish(hp_ptr, &hp[0], CFI_attribute_other, + CFI_type_double , hp_nbytes, 1, hp_extent) + + CFI_establish(hxy_ptr, &hxy[0], CFI_attribute_other, + CFI_type_double , hxy_nbytes, 1, hxy_extent) + + c__pdafomi_localize_covar_serial_noniso_locweights(&i_obs, + &iobs_all, &dim, + &dim_obs, + locweights_ptr, + cradius_ptr, + sradius_ptr, + coords_ptr, + hp_ptr, hxy_ptr) + + return hp_np, hxy_np + + +def localize_covar_serial_noniso(int i_obs, int iobs_all, int dim, + int dim_obs, int locweight, double [::1] cradius, + double [::1] sradius, double [::1,:] coords, double [::1] hp, + double [::1] hxy): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + iobs_all : int + Index of current observation + dim : int + State dimension + dim_obs : int + Overall full observation dimension + locweight : int + Localization weight type + cradius : ndarray[np.float64, ndim=1] + Vector of localization cut-off radii + Array shape: (:) + sradius : ndarray[np.float64, ndim=1] + Vector of support radii of localization function + Array shape: (:) + coords : ndarray[np.float64, ndim=2] + Coordinates of state vector elements + Array shape: (:,:) + hp : ndarray[np.float64, ndim=1] + Vector HP, dimension (dim) + Array shape: (:) + hxy : ndarray[np.float64, ndim=1] + Matrix HXY, dimension (nobs) + Array shape: (:) + + Returns + ------- + hp : ndarray[np.float64, ndim=1] + Vector HP, dimension (dim) + Array shape: (:) + hxy : ndarray[np.float64, ndim=1] + Matrix HXY, dimension (nobs) + Array shape: (:) + """ + cdef CFI_cdesc_rank1 hp_cfi + cdef CFI_cdesc_t *hp_ptr = &hp_cfi + cdef size_t hp_nbytes = hp.nbytes + cdef CFI_index_t hp_extent[1] + hp_extent[0] = hp.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] hp_np = np.asarray(hp, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 hxy_cfi + cdef CFI_cdesc_t *hxy_ptr = &hxy_cfi + cdef size_t hxy_nbytes = hxy.nbytes + cdef CFI_index_t hxy_extent[1] + hxy_extent[0] = hxy.shape[0] + cdef cnp.ndarray[cnp.float64_t, ndim=1, mode="fortran", negative_indices=False, cast=False] hxy_np = np.asarray(hxy, dtype=np.float64, order="F") + cdef CFI_cdesc_rank1 cradius_cfi + cdef CFI_cdesc_t *cradius_ptr = &cradius_cfi + cdef size_t cradius_nbytes = cradius.nbytes + cdef CFI_index_t cradius_extent[1] + cradius_extent[0] = cradius.shape[0] + cdef CFI_cdesc_rank1 sradius_cfi + cdef CFI_cdesc_t *sradius_ptr = &sradius_cfi + cdef size_t sradius_nbytes = sradius.nbytes + cdef CFI_index_t sradius_extent[1] + sradius_extent[0] = sradius.shape[0] + cdef CFI_cdesc_rank2 coords_cfi + cdef CFI_cdesc_t *coords_ptr = &coords_cfi + cdef size_t coords_nbytes = coords.nbytes + cdef CFI_index_t coords_extent[2] + coords_extent[0] = coords.shape[0] + coords_extent[1] = coords.shape[1] + with nogil: + CFI_establish(cradius_ptr, &cradius[0], CFI_attribute_other, + CFI_type_double , cradius_nbytes, 1, cradius_extent) + + CFI_establish(sradius_ptr, &sradius[0], CFI_attribute_other, + CFI_type_double , sradius_nbytes, 1, sradius_extent) + + CFI_establish(coords_ptr, &coords[0,0], CFI_attribute_other, + CFI_type_double , coords_nbytes, 2, coords_extent) + + CFI_establish(hp_ptr, &hp[0], CFI_attribute_other, + CFI_type_double , hp_nbytes, 1, hp_extent) + + CFI_establish(hxy_ptr, &hxy[0], CFI_attribute_other, + CFI_type_double , hxy_nbytes, 1, hxy_extent) + + c__pdafomi_localize_covar_serial_noniso(&i_obs, &iobs_all, &dim, + &dim_obs, &locweight, + cradius_ptr, sradius_ptr, + coords_ptr, hp_ptr, hxy_ptr) + + return hp_np, hxy_np + + +def init_dim_obs_l_iso_old(int i_obs, double [::1] coords_l, + int locweight, double cradius, double sradius, int cnt_obs_l): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + coords_l : ndarray[np.float64, ndim=1] + Coordinates of current analysis domain + Array shape: (:) + locweight : int + Type of localization function + cradius : double + Localization cut-off radius (single or vector) + sradius : double + Support radius of localization function (single or vector) + cnt_obs_l : int + Local dimension of current observation vector + + Returns + ------- + cnt_obs_l : int + Local dimension of current observation vector + """ + cdef CFI_cdesc_rank1 coords_l_cfi + cdef CFI_cdesc_t *coords_l_ptr = &coords_l_cfi + cdef size_t coords_l_nbytes = coords_l.nbytes + cdef CFI_index_t coords_l_extent[1] + coords_l_extent[0] = coords_l.shape[0] + with nogil: + CFI_establish(coords_l_ptr, &coords_l[0], CFI_attribute_other, + CFI_type_double , coords_l_nbytes, 1, coords_l_extent) + + c__pdafomi_init_dim_obs_l_iso_old(&i_obs, coords_l_ptr, &locweight, + &cradius, &sradius, &cnt_obs_l) + + return cnt_obs_l + + +def init_dim_obs_l_noniso_old(int i_obs, double [::1] coords_l, + int locweight, double [::1] cradius, double [::1] sradius, int cnt_obs_l): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + coords_l : ndarray[np.float64, ndim=1] + Coordinates of current analysis domain + Array shape: (:) + locweight : int + Type of localization function + cradius : ndarray[np.float64, ndim=1] + Vector of localization cut-off radii + Array shape: (:) + sradius : ndarray[np.float64, ndim=1] + Vector of support radii of localization function + Array shape: (:) + cnt_obs_l : int + Local dimension of current observation vector + + Returns + ------- + cnt_obs_l : int + Local dimension of current observation vector + """ + cdef CFI_cdesc_rank1 coords_l_cfi + cdef CFI_cdesc_t *coords_l_ptr = &coords_l_cfi + cdef size_t coords_l_nbytes = coords_l.nbytes + cdef CFI_index_t coords_l_extent[1] + coords_l_extent[0] = coords_l.shape[0] + cdef CFI_cdesc_rank1 cradius_cfi + cdef CFI_cdesc_t *cradius_ptr = &cradius_cfi + cdef size_t cradius_nbytes = cradius.nbytes + cdef CFI_index_t cradius_extent[1] + cradius_extent[0] = cradius.shape[0] + cdef CFI_cdesc_rank1 sradius_cfi + cdef CFI_cdesc_t *sradius_ptr = &sradius_cfi + cdef size_t sradius_nbytes = sradius.nbytes + cdef CFI_index_t sradius_extent[1] + sradius_extent[0] = sradius.shape[0] + with nogil: + CFI_establish(coords_l_ptr, &coords_l[0], CFI_attribute_other, + CFI_type_double , coords_l_nbytes, 1, coords_l_extent) + + CFI_establish(cradius_ptr, &cradius[0], CFI_attribute_other, + CFI_type_double , cradius_nbytes, 1, cradius_extent) + + CFI_establish(sradius_ptr, &sradius[0], CFI_attribute_other, + CFI_type_double , sradius_nbytes, 1, sradius_extent) + + c__pdafomi_init_dim_obs_l_noniso_old(&i_obs, coords_l_ptr, + &locweight, cradius_ptr, + sradius_ptr, &cnt_obs_l) + + return cnt_obs_l + + +def init_dim_obs_l_noniso_locweights_old(int i_obs, double [::1] coords_l, + int [::1] locweights, double [::1] cradius, double [::1] sradius, + int cnt_obs_l): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + i_obs : int + index into observation arrays + coords_l : ndarray[np.float64, ndim=1] + Coordinates of current analysis domain + Array shape: (:) + locweights : ndarray[np.intc, ndim=1] + Types of localization function + Array shape: (:) + cradius : ndarray[np.float64, ndim=1] + Vector of localization cut-off radii + Array shape: (:) + sradius : ndarray[np.float64, ndim=1] + Vector of support radii of localization function + Array shape: (:) + cnt_obs_l : int + Local dimension of current observation vector + + Returns + ------- + cnt_obs_l : int + Local dimension of current observation vector + """ + cdef CFI_cdesc_rank1 coords_l_cfi + cdef CFI_cdesc_t *coords_l_ptr = &coords_l_cfi + cdef size_t coords_l_nbytes = coords_l.nbytes + cdef CFI_index_t coords_l_extent[1] + coords_l_extent[0] = coords_l.shape[0] + cdef CFI_cdesc_rank1 locweights_cfi + cdef CFI_cdesc_t *locweights_ptr = &locweights_cfi + cdef size_t locweights_nbytes = locweights.nbytes + cdef CFI_index_t locweights_extent[1] + locweights_extent[0] = locweights.shape[0] + cdef CFI_cdesc_rank1 cradius_cfi + cdef CFI_cdesc_t *cradius_ptr = &cradius_cfi + cdef size_t cradius_nbytes = cradius.nbytes + cdef CFI_index_t cradius_extent[1] + cradius_extent[0] = cradius.shape[0] + cdef CFI_cdesc_rank1 sradius_cfi + cdef CFI_cdesc_t *sradius_ptr = &sradius_cfi + cdef size_t sradius_nbytes = sradius.nbytes + cdef CFI_index_t sradius_extent[1] + sradius_extent[0] = sradius.shape[0] + with nogil: + CFI_establish(coords_l_ptr, &coords_l[0], CFI_attribute_other, + CFI_type_double , coords_l_nbytes, 1, coords_l_extent) + + CFI_establish(locweights_ptr, &locweights[0], CFI_attribute_other, + CFI_type_int , locweights_nbytes, 1, locweights_extent) + + CFI_establish(cradius_ptr, &cradius[0], CFI_attribute_other, + CFI_type_double , cradius_nbytes, 1, cradius_extent) + + CFI_establish(sradius_ptr, &sradius[0], CFI_attribute_other, + CFI_type_double , sradius_nbytes, 1, sradius_extent) + + c__pdafomi_init_dim_obs_l_noniso_locweights_old(&i_obs, + coords_l_ptr, + locweights_ptr, + cradius_ptr, + sradius_ptr, &cnt_obs_l) + + return cnt_obs_l + + +def deallocate_obs(int i_obs): + r"""Deallocate OMI-internal obsrevation arrays + + This function should not be called by users + because it is called internally in PDAF. + + Parameters + ---------- + i_obs : int + index of observations + """ + with nogil: + c__pdafomi_deallocate_obs(&i_obs) + + + diff --git a/pyPDAF/source/src/pyPDAF/PDAFomi/meson.build b/pyPDAF/source/src/pyPDAF/PDAFomi/meson.build new file mode 100644 index 0000000000000000000000000000000000000000..0ffdb621556b401fc70ceaad56f8507f31001c6b --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFomi/meson.build @@ -0,0 +1,29 @@ +pypdaf_sources = files('assim.pyx', + 'diag.pyx', + 'internal.pyx', + 'legacy.pyx', + '_pdafomi_c.pyx', + 'put.pyx', + 'setter.pyx' + ) + +foreach file :pypdaf_sources + + cython_ext = python.extension_module( + fs.stem(file), + file, + link_with: [pdafc_lib], + dependencies : [mpi, dep_py, blas_dep, fruntime_dep], + include_directories: include_directories([incdir_numpy ]), + c_args: c_cython_args, + link_args: link_args, + cython_args : cython_args, + link_language: 'fortran', + subdir: 'pyPDAF' / 'PDAFomi', + install: true, + install_rpath: '$ORIGIN' + ) +endforeach + +python.install_sources(['__init__.py', 'py.typed', '_pdafomi_c.pyi', + 'diag.pyi', 'setter.pyi'], subdir: 'pyPDAF/PDAFomi/') diff --git a/pyPDAF/source/src/pyPDAF/PDAFomi/put.pxd b/pyPDAF/source/src/pyPDAF/PDAFomi/put.pxd new file mode 100644 index 0000000000000000000000000000000000000000..a071c6488ad4ebef31f232f58c0cdf184311a0a3 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFomi/put.pxd @@ -0,0 +1,337 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t +cdef extern void c__pdafomi_put_state_local_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_global_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_enkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_lenkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__localize_covar_pdaf)(int* , int* , double* , double* ), + void (*c__add_obs_err_pdaf)(int* , int* , double* ), + void (*c__init_obs_covar_pdaf)(int* , int* , int* , double* , double* , + bint* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_nonlin_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__likelihood_pdaf)(int* , int* , double* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_lnetf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_lknetf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__prodrinva_hyb_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* , double* ), + void (*c__likelihood_l_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__likelihood_hyb_l_pdaf)(int* , int* , int* , double* , + double* , double* , double* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_3dvar( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_en3dvar_estkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_en3dvar_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_hyb3dvar_estkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_hyb3dvar_lestkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_3dvar_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_en3dvar_estkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_en3dvar_lestkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_hyb3dvar_estkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_hyb3dvar_lestkf_nondiagr( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_pdaf)(int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_ens_pdaf)(int* , int* , int* , int* , double* , double* , + double* ), + void (*c__cvt_adj_ens_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__cvt_pdaf)(int* , int* , int* , double* , double* ), + void (*c__cvt_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_lin_pdaf)(int* , int* , int* , double* , double* ), + void (*c__obs_op_adj_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prodrinva_l_pdaf)(int* , int* , int* , int* , double* , + double* , double* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_local( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__init_n_domains_p_pdaf)(int* , int* ), + void (*c__init_dim_l_pdaf)(int* , int* , int* ), + void (*c__init_dim_obs_l_pdaf)(int* , int* , int* , int* ), + void (*c__g2l_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + void (*c__l2g_state_pdaf)(int* , int* , int* , double* , int* , + double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_global( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_lenkf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + void (*c__localize_covar_pdaf)(int* , int* , double* , double* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_ensrf( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_pdaf)(int* , int* ), + void (*c__obs_op_pdaf)(int* , int* , int* , double* , double* ), + void (*c__localize_covar_serial_pdaf)(int* , int* , int* , double* , + double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + +cdef extern void c__pdafomi_put_state_generate_obs( + void (*c__collect_state_pdaf)(int* , double* ), + void (*c__init_dim_obs_f_pdaf)(int* , int* ), + void (*c__obs_op_f_pdaf)(int* , int* , int* , double* , double* ), + void (*c__get_obs_f_pdaf)(int* , int* , double* ), + void (*c__prepoststep_pdaf)(int* , int* , int* , int* , int* , + double* , double* , double* , int* ), + int* outflag) noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/PDAFomi/put.pyx b/pyPDAF/source/src/pyPDAF/PDAFomi/put.pyx new file mode 100644 index 0000000000000000000000000000000000000000..21e15b5a83d847afb587b3e3dcf5d4436b4d1214 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFomi/put.pyx @@ -0,0 +1,6279 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + +try: + import mpi4py + mpi4py.rc.initialize = False +except ImportError: + pass + +# Global error handler +def global_except_hook(exctype, value, traceback): + from traceback import print_exception + try: + import mpi4py.MPI + + if mpi4py.MPI.Is_initialized(): + try: + sys.stderr.write('Uncaught exception was ''detected on rank {}.\n'.format( + mpi4py.MPI.COMM_WORLD.Get_rank())) + print_exception(exctype, value, traceback) + sys.stderr.write("\n") + sys.stderr.flush() + finally: + try: + mpi4py.MPI.COMM_WORLD.Abort(1) + except Exception as e: + sys.stderr.write('MPI Abort failed, this process will hang.\n') + sys.stderr.flush() + raise e + else: + sys.__excepthook__(exctype, value, traceback) + except ImportError: + sys.__excepthook__(exctype, value, traceback) + +sys.excepthook = global_except_hook + +def put_state_local_nondiagr(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__prepoststep_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__prodrinva_l_pdaf, + py__g2l_state_pdaf, py__l2g_state_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__prodrinva_l_pdaf : Callable + Provide product of inverse of R with matrix A + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from local state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + cdef int outflag + with nogil: + c__pdafomi_put_state_local_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, &outflag) + + return outflag + + +def put_state_global_nondiagr(py__collect_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__prodrinva_pdaf, + py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdafomi_put_state_global_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_enkf_nondiagr(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__add_obs_err_pdaf, py__init_obs_covar_pdaf, + py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__add_obs_err_pdaf : Callable + Add observation error covariance matrix + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Dimension of observation vector + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + py__init_obs_covar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs : int + Global size of observation vector + dim_obs_p : int + Size of process-local observation vector + obs_p : ndarray[np.float64, ndim=1] + Process-local vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + covar : ndarray[np.float64, ndim=2] + Observation error covariance matrix + Array shape: (dim_obs_p,dim_obs_p) + isdiag : bint + + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdafomi_put_state_enkf_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_lenkf_nondiagr(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__prepoststep_pdaf, py__localize_covar_pdaf, + py__add_obs_err_pdaf, py__init_obs_covar_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__localize_covar_pdaf : Callable + Apply localization to HP and HPH^T + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + dim_obs : int + number of observations + hp_p : ndarray[np.float64, ndim=2] + pe local part of matrix hp + Array shape: (dim_obs, dim_p) + hph : ndarray[np.float64, ndim=2] + matrix hph + Array shape: (dim_obs, dim_obs) + + Callback Returns + ---------------- + hp_p : ndarray[np.float64, ndim=2] + pe local part of matrix hp + Array shape: (dim_obs, dim_p) + hph : ndarray[np.float64, ndim=2] + matrix hph + Array shape: (dim_obs, dim_obs) + + py__add_obs_err_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Dimension of observation vector + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Matrix to that observation covariance R is added + Array shape: (dim_obs_p,dim_obs_p) + + py__init_obs_covar_pdaf : Callable + Initialize mean observation error variance + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs : int + Global size of observation vector + dim_obs_p : int + Size of process-local observation vector + obs_p : ndarray[np.float64, ndim=1] + Process-local vector of observations + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + covar : ndarray[np.float64, ndim=2] + Observation error covariance matrix + Array shape: (dim_obs_p,dim_obs_p) + isdiag : bint + + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.localize_covar_pdaf = py__localize_covar_pdaf + pdaf_cb.add_obs_err_pdaf = py__add_obs_err_pdaf + pdaf_cb.init_obs_covar_pdaf = py__init_obs_covar_pdaf + cdef int outflag + with nogil: + c__pdafomi_put_state_lenkf_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__localize_covar_pdaf, + pdaf_cb.c__add_obs_err_pdaf, + pdaf_cb.c__init_obs_covar_pdaf, + &outflag) + + return outflag + + +def put_state_nonlin_nondiagr(py__collect_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__likelihood_pdaf, + py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__likelihood_pdaf : Callable + Compute likelihood + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + resid : ndarray[np.float64, ndim=1] + Input vector holding the residual + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + likely : double + Output value of the likelihood + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.likelihood_pdaf = py__likelihood_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdafomi_put_state_nonlin_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__likelihood_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_lnetf_nondiagr(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__prepoststep_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__likelihood_l_pdaf, + py__g2l_state_pdaf, py__l2g_state_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__likelihood_l_pdaf : Callable + Compute likelihood and apply localization + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from local state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + cdef int outflag + with nogil: + c__pdafomi_put_state_lnetf_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, &outflag) + + return outflag + + +def put_state_lknetf_nondiagr(py__collect_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__prepoststep_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__prodrinva_l_pdaf, + py__prodrinva_hyb_l_pdaf, py__likelihood_l_pdaf, + py__likelihood_hyb_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A on local analysis domain + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__prodrinva_hyb_l_pdaf : Callable + Product R^-1 A on local analysis domain with hybrid weight + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + dim_ens : int + Number of the columns in the matrix processes here. This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, dim_ens) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, dim_ens) + + py__likelihood_l_pdaf : Callable + Compute likelihood and apply localization + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + nput vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__likelihood_hyb_l_pdaf : Callable + Compute likelihood and apply localization with tempering + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + gamma : double + Hybrid weight provided by PDAF + + Callback Returns + ---------------- + resid_l : ndarray[np.float64, ndim=1] + Input vector holding the local residual + Array shape: (dim_obs_l) + likely_l : double + Output value of the local likelihood + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from local state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.prodrinva_hyb_l_pdaf = py__prodrinva_hyb_l_pdaf + pdaf_cb.likelihood_l_pdaf = py__likelihood_l_pdaf + pdaf_cb.likelihood_hyb_l_pdaf = py__likelihood_hyb_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + cdef int outflag + with nogil: + c__pdafomi_put_state_lknetf_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__prodrinva_hyb_l_pdaf, + pdaf_cb.c__likelihood_l_pdaf, + pdaf_cb.c__likelihood_hyb_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + &outflag) + + return outflag + + +def put_state_3dvar(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__prepoststep_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_put_state_3dvar` + or :func:`pyPDAF.PDAF.omi_put_state_3dvar_nondiagR`. + + PDAF-OMI modules require fewer user-supplied + functions and improved efficiency. + + 3DVar DA for a single DA step. + + Compared to :func:`pyPDAF.PDAF.assimilate_3dvar`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will not + be assigned by user-supplied functions as well. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + When 3DVar is used, the background error covariance matrix + has to be modelled for cotrol variable transformation. + This is a deterministic filtering scheme so no ensemble + and parallelisation is needed. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. Iterative optimisation: + 1. py__cvt_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_pdaf + 6. core DA algorithm + 7. py__cvt_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_put_state_3dvar` + and :func:`pyPDAF.PDAF.omi_put_state_3dvar_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdafomi_put_state_3dvar(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_en3dvar_estkf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prepoststep_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_put_state_en3dvar_estkf` + or :func:`pyPDAF.PDAF.omi_put_state_en3dvar_estkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + 3DEnVar for a single DA step. + + Compared to :func:`pyPDAF.PDAF.assimilate_en3dvar_estkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will not be + assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The background error covariance matrix is + estimated by an ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An ESTKF is used along with 3DEnVar to + generate ensemble perturbations. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core 3DEnVar algorithm + 7. py__cvt_ens_pdaf + 8. ESTKF: + 1. py__init_dim_obs_pdaf + 2. py__obs_op_pdaf (for ensemble mean) + 3. py__init_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. py__init_obsvar_pdaf + (only relevant for adaptive forgetting factor schemes) + 6. py__prodRinvA_pdaf + 7. core ESTKF algorithm + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_put_state_en3dvar_estkf` + and :func:`pyPDAF.PDAF.omi_put_state_en3dvar_estkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdafomi_put_state_en3dvar_estkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_en3dvar_lestkf(py__collect_state_pdaf, + py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__prepoststep_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf` + or :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + 3DEnVar for a single DA step without post-processing, + distributing analysis, and setting next observation step, + where the ensemble anomaly is generated by LESTKF. + + Compared to :func:`pyPDAF.PDAF.assimilate_en3dvar_lestkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The background error covariance matrix is estimated by ensemble. + The 3DEnVar only calculates the analysis of the ensemble mean. + An LESTKF is used to generate ensemble perturbations. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. Starting the iterative optimisation: + 1. py__cvt_ens_pdaf + 2. py__obs_op_lin_pdaf + 3. py__prodRinvA_pdaf + 4. py__obs_op_adj_pdaf + 5. py__cvt_adj_ens_pdaf + 6. core DA algorithm + 7. py__cvt_ens_pdaf + 8. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__init_obs_pdaf + (if global adaptive forgetting factor is used + `type_forget=1` in :func:`pyPDAF.PDAF.init`) + 5. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise mean ensemble in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting factor + `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf` + and :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from local state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdafomi_put_state_en3dvar_lestkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_hyb3dvar_estkf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__cvt_pdaf, + py__cvt_adj_pdaf, py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, + py__prepoststep_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_estkf` + or :func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_estkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Hybrid 3DEnVar for a single DA step where + the background error covariance is hybridised by + a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + + Compared to :func:`pyPDAF.PDAF.assimilate_hyb3dvar_estkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + ESTKF in this implementation. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. the iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core 3DEnVar algorithm + 7. py__cvt_pdaf + 8. py__cvt_ens_pdaf + 9. Perform ESTKF: + 1. py__init_dim_obs_pdaf + 2. py__obs_op_pdaf + (for ensemble mean) + 3. py__init_obs_pdaf + 4. py__obs_op_pdaf + (for each ensemble member) + 5. py__init_obsvar_pdaf + (only relevant for adaptive + forgetting factor schemes) + 6. py__prodRinvA_pdaf + 7. core ESTKF algorithm + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_estkf` + and :func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_estkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__cvt_ens_pdaf : Callable + Apply ensemble control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint ensemble control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdafomi_put_state_hyb3dvar_estkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_hyb3dvar_lestkf(py__collect_state_pdaf, + py__init_dim_obs_f_pdaf, py__obs_op_f_pdaf, py__cvt_ens_pdaf, + py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, + py__l2g_state_pdaf, py__prepoststep_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf` + or :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Hybrid 3DEnVar for a single DA step using + non-diagnoal observation error covariance matrix + without post-processing, distributing analysis, + and setting next observation step, where + the background error covariance is hybridised by + a static background error covariance, + and a flow-dependent background error covariance + estimated from ensemble. + + Compared to :func:`pyPDAF.PDAF.assimilate_hyb3dvar_lestkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The 3DVar generates an ensemble mean and + the ensemble perturbation is generated by + LESTKF in this implementation. + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf + 5. py__init_obs_pdaf + 6. The iterative optimisation: + 1. py__cvt_pdaf + 2. py__cvt_ens_pdaf + 3. py__obs_op_lin_pdaf + 4. py__prodRinvA_pdaf + 5. py__obs_op_adj_pdaf + 6. py__cvt_adj_pdaf + 7. py__cvt_adj_ens_pdaf + 8. core DA algorithm + 7. py__cvt_pdaf + 8. py__cvt_ens_pdaf + 9. Perform LESTKF: + 1. py__init_n_domains_p_pdaf + 2. py__init_dim_obs_pdaf + 3. py__obs_op_pdaf + (for each ensemble member) + 4. py__init_obs_pdaf + (if global adaptive forgetting factor + `type_forget=1` in :func:`pyPDAF.PDAF.init`) + 5. py__init_obsvar_pdaf + (if global adaptive forgetting factor is used) + 6. loop over each local domain: + 1. py__init_dim_l_pdaf + 2. py__init_dim_obs_l_pdaf + 3. py__g2l_state_pdaf + 4. py__g2l_obs_pdaf + (localise mean ensemble in observation space) + 5. py__init_obs_l_pdaf + 6. py__g2l_obs_pdaf + (localise each ensemble member + in observation space) + 7. py__init_obsvar_l_pdaf + (only called if local adaptive forgetting + factor `type_forget=2` is used) + 8. py__prodRinvA_l_pdaf + 9. core DA algorithm + 10. py__l2g_state_pdaf + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf` + and :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf_nondiagR` + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from local state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdafomi_put_state_hyb3dvar_lestkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_3dvar_nondiagr(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__prodrinva_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdafomi_put_state_3dvar_nondiagr(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_en3dvar_estkf_nondiagr(py__collect_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__prodrinva_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdafomi_put_state_en3dvar_estkf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_en3dvar_lestkf_nondiagr(py__collect_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__prodrinva_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__obs_op_lin_pdaf, + py__obs_op_adj_pdaf, py__prodrinva_l_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, + py__l2g_state_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from local state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdafomi_put_state_en3dvar_lestkf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_hyb3dvar_estkf_nondiagr(py__collect_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__prodrinva_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply ensemble control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint ensemble control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdafomi_put_state_hyb3dvar_estkf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_hyb3dvar_lestkf_nondiagr(py__collect_state_pdaf, + py__init_dim_obs_pdaf, py__obs_op_pdaf, py__prodrinva_pdaf, + py__cvt_ens_pdaf, py__cvt_adj_ens_pdaf, py__cvt_pdaf, py__cvt_adj_pdaf, + py__obs_op_lin_pdaf, py__obs_op_adj_pdaf, py__prodrinva_l_pdaf, + py__init_n_domains_p_pdaf, py__init_dim_l_pdaf, + py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, py__l2g_state_pdaf, + py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prodrinva_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_p : int + Number of observations at current time step (i.e. the size of the observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one + (or the rank of the initial covariance matrix) + obs_p : ndarray[np.float64, ndim=1] + Vector of observations + Array shape: (dim_obs_p) + a_p : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_p, rank) + + Callback Returns + ---------------- + c_p : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_p, rank) + + py__cvt_ens_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local dimension of state + dim_ens : int + Ensemble size + dim_cvec_ens : int + Dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + v_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec_ens) + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local state increment + Array shape: (dim_p) + + py__cvt_adj_ens_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_ens : int + Ensemble size + dim_cv_ens_p : int + PE-local dimension of control vector + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + vcv_p : ndarray[np.float64, ndim=1] + PE-local input vector + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local result vector + Array shape: (dim_cv_ens_p) + + py__cvt_pdaf : Callable + Apply control vector transform matrix to control vector + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + Callback Returns + ---------------- + vv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + + py__cvt_adj_pdaf : Callable + Apply adjoint control vector transform matrix + + Callback Parameters + ------------------- + iter : int + Iteration of optimization + dim_p : int + PE-local observation dimension + dim_cvec : int + Dimension of control vector + vcv_p : ndarray[np.float64, ndim=1] + PE-local result vector (state vector increment) + Array shape: (dim_p) + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + Callback Returns + ---------------- + cv_p : ndarray[np.float64, ndim=1] + PE-local control vector + Array shape: (dim_cvec) + + py__obs_op_lin_pdaf : Callable + Linearized observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + + py__obs_op_adj_pdaf : Callable + Adjoint observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + PE-local dimension of state + dim_obs_p : int + Dimension of observed state + m_state_p : ndarray[np.float64, ndim=1] + PE-local observed state + Array shape: (dim_obs_p) + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + Array shape: (dim_p) + + py__prodrinva_l_pdaf : Callable + Provide product R^-1 A + + Callback Parameters + ------------------- + domain_p : int + Index of current local analysis domain + step : int + Current time step + dim_obs_l : int + Number of local observations at current time step (i.e. the size of the local observation vector) + rank : int + Number of the columns in the matrix processes here. + This is usually the ensemble size minus one (or the rank of the initial covariance matrix) + obs_l : ndarray[np.float64, ndim=1] + Local vector of observations + Array shape: (dim_obs_l) + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + + Callback Returns + ---------------- + a_l : ndarray[np.float64, ndim=2] + Input matrix provided by PDAF + Array shape: (dim_obs_l, rank) + c_l : ndarray[np.float64, ndim=2] + Output matrix + Array shape: (dim_obs_l, rank) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from local state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prodrinva_pdaf = py__prodrinva_pdaf + pdaf_cb.cvt_ens_pdaf = py__cvt_ens_pdaf + pdaf_cb.cvt_adj_ens_pdaf = py__cvt_adj_ens_pdaf + pdaf_cb.cvt_pdaf = py__cvt_pdaf + pdaf_cb.cvt_adj_pdaf = py__cvt_adj_pdaf + pdaf_cb.obs_op_lin_pdaf = py__obs_op_lin_pdaf + pdaf_cb.obs_op_adj_pdaf = py__obs_op_adj_pdaf + pdaf_cb.prodrinva_l_pdaf = py__prodrinva_l_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdafomi_put_state_hyb3dvar_lestkf_nondiagr( + pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prodrinva_pdaf, + pdaf_cb.c__cvt_ens_pdaf, + pdaf_cb.c__cvt_adj_ens_pdaf, + pdaf_cb.c__cvt_pdaf, + pdaf_cb.c__cvt_adj_pdaf, + pdaf_cb.c__obs_op_lin_pdaf, + pdaf_cb.c__obs_op_adj_pdaf, + pdaf_cb.c__prodrinva_l_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, + pdaf_cb.c__prepoststep_pdaf, + &outflag) + + return outflag + + +def put_state_local(py__collect_state_pdaf, py__init_dim_obs_f_pdaf, + py__obs_op_f_pdaf, py__prepoststep_pdaf, py__init_n_domains_p_pdaf, + py__init_dim_l_pdaf, py__init_dim_obs_l_pdaf, py__g2l_state_pdaf, + py__l2g_state_pdaf, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of full observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Full observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__init_n_domains_p_pdaf : Callable + Provide number of local analysis domains + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + n_domains_p : int + pe-local number of analysis domains + + py__init_dim_l_pdaf : Callable + Init state dimension for local ana. domain + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + + Callback Returns + ---------------- + dim_l : int + local state dimension + + py__init_dim_obs_l_pdaf : Callable + Initialize local dimimension of obs. vector + + Callback Parameters + ------------------- + domain_p : int + index of current local analysis domain + step : int + current time step + dim_obs_f : int + full dimension of observation vector + + Callback Returns + ---------------- + dim_obs_l : int + local dimension of observation vector + + py__g2l_state_pdaf : Callable + Get state on local ana. domain from full state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + dim_l : int + local state dimension + + Callback Returns + ---------------- + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + + py__l2g_state_pdaf : Callable + Init full state from local state + + Callback Parameters + ------------------- + step : int + current time step + domain_p : int + current local analysis domain + dim_l : int + local state dimension + state_l : ndarray[np.float64, ndim=1] + state vector on local analysis domain + Array shape: (dim_l) + dim_p : int + pe-local full state dimension + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local full state vector + Array shape: (dim_p) + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.init_n_domains_p_pdaf = py__init_n_domains_p_pdaf + pdaf_cb.init_dim_l_pdaf = py__init_dim_l_pdaf + pdaf_cb.init_dim_obs_l_pdaf = py__init_dim_obs_l_pdaf + pdaf_cb.g2l_state_pdaf = py__g2l_state_pdaf + pdaf_cb.l2g_state_pdaf = py__l2g_state_pdaf + with nogil: + c__pdafomi_put_state_local(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__init_n_domains_p_pdaf, + pdaf_cb.c__init_dim_l_pdaf, + pdaf_cb.c__init_dim_obs_l_pdaf, + pdaf_cb.c__g2l_state_pdaf, + pdaf_cb.c__l2g_state_pdaf, &outflag) + + return outflag + + +def put_state_global(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__prepoststep_pdaf, int outflag): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + outflag : int + Status flag + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + with nogil: + c__pdafomi_put_state_global(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_lenkf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__prepoststep_pdaf, py__localize_covar_pdaf): + """It is recommended to use + :func:`pyPDAF.PDAF.omi_put_state_lenkf` + or :func:`pyPDAF.PDAF.omi_put_state_lenkf_nondiagR`. + + PDAF-OMI modules require fewer user-supplied functions + and improved efficiency. + + Stochastic EnKF (ensemble Kalman filter) + with covariance localisation [1]_ + for a single DA step without OMI. + + Compared to :func:`pyPDAF.PDAF.assimilate_lenkf`, + this function has no :func:`get_state` call. + This means that the analysis is not post-processed, + and distributed to the model forecast + by user-supplied functions. The next DA step will + not be assigned by user-supplied functions as well. + This function is typically used when there are + not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + This is the only scheme for covariance localisation in PDAF. + + This function should be called at each model time step. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pdaf (for each ensemble member) + 5. py__localize_pdaf + 6. py__add_obs_err_pdaf + 7. py__init_obs_pdaf + 8. py__init_obscovar_pdaf + 9. py__obs_op_pdaf (repeated to reduce storage) + 10. core DA algorith + + .. deprecated:: 1.0.0 + + This function is replaced by + :func:`pyPDAF.PDAF.omi_put_state_lenkf` + and :func:`pyPDAF.PDAF.omi_put_state_lenkf_nondiagR` + + References + ---------- + .. [1] Houtekamer, P. L., and H. L. Mitchell (1998): + Data Assimilation Using an Ensemble Kalman + Filter Technique. + Mon. Wea. Rev., 126, 796–811, + doi: 10.1175/1520-0493(1998)126<0796:DAUAEK>2.0.CO;2. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + py__localize_covar_pdaf : Callable + Apply localization to HP and HPH^T + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + dim_obs : int + number of observations + hp_p : ndarray[np.float64, ndim=2] + pe local part of matrix hp + Array shape: (dim_obs, dim_p) + hph : ndarray[np.float64, ndim=2] + matrix hph + Array shape: (dim_obs, dim_obs) + + Callback Returns + ---------------- + hp_p : ndarray[np.float64, ndim=2] + pe local part of matrix hp + Array shape: (dim_obs, dim_p) + hph : ndarray[np.float64, ndim=2] + matrix hph + Array shape: (dim_obs, dim_obs) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + pdaf_cb.localize_covar_pdaf = py__localize_covar_pdaf + cdef int outflag + with nogil: + c__pdafomi_put_state_lenkf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__prepoststep_pdaf, + pdaf_cb.c__localize_covar_pdaf, &outflag) + + return outflag + + +def put_state_ensrf(py__collect_state_pdaf, py__init_dim_obs_pdaf, + py__obs_op_pdaf, py__localize_covar_serial_pdaf, py__prepoststep_pdaf): + """Checking the corresponding PDAF documentation in https://pdaf.awi.de + For internal subroutines checking corresponding PDAF comments. + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector + (local part in case of parallel decomposed state) + dim_obs_p : int + Size of PE-local observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector + (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__localize_covar_serial_pdaf : Callable + Apply localization to HP and HXY + + Callback Parameters + ------------------- + iobs : int + Index of current observation + dim_p : int + Process-local state dimension + dim_obs : int + Number of observations + hp_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HP for observation iobs + Array shape: (dim_p) + hxy_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HX(HX_all) for full observations + Array shape: (dim_obs) + + Callback Returns + ---------------- + hp_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HP for observation iobs + Array shape: (dim_p) + hxy_p : ndarray[np.float64, ndim=1] + Process-local part of matrix HX(HX_all) for full observations + Array shape: (dim_obs) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_pdaf = py__init_dim_obs_pdaf + pdaf_cb.obs_op_pdaf = py__obs_op_pdaf + pdaf_cb.localize_covar_serial_pdaf = py__localize_covar_serial_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdafomi_put_state_ensrf(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_pdaf, + pdaf_cb.c__obs_op_pdaf, + pdaf_cb.c__localize_covar_serial_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + +def put_state_generate_obs(py__collect_state_pdaf, py__init_dim_obs_f_pdaf, + py__obs_op_f_pdaf, py__get_obs_f_pdaf, py__prepoststep_pdaf): + """Generation of synthetic observations + based on given error statistics and observation operator + without post-processing, distributing analysis, + and setting next observation step. + + When diagonal observation error covariance matrix is used, + it is recommended to use + :func:`pyPDAF.PDAF.omi_generate_obs` functionalities + for fewer user-supplied functions and improved efficiency. + + The generated synthetic observations are + based on each member of model forecast. + Therefore, an ensemble of observations can be obtained. + In a typical experiment, + one may only need one ensemble member. + + Compared to :func:`pyPDAF.PDAF.generate_obs`, + this function has no :func:`get_state` call. + This means that the next DA step will + not be assigned by user-supplied functions. + This function is typically used when there + are not enough CPUs to run the ensemble in parallel, + and some ensemble members have to be run serially. + The :func:`pyPDAF.PDAF.get_state` function follows this + function call to ensure the sequential DA. + + The implementation strategy is similar to + an assimilation step. This means that, + one can reuse many user-supplied functions for + assimilation and observation generation. + + User-supplied functions are executed in the following sequence: + 1. py__collect_state_pdaf + 2. py__prepoststep_state_pdaf + 3. py__init_dim_obs_pdaf + 4. py__obs_op_pda + 5. py__init_obserr_f_pdaf + 6. py__get_obs_f_pdaf + + Parameters + ---------- + py__collect_state_pdaf : Callable + Routine to collect a state vector + + Callback Parameters + ------------------- + dim_p : int + pe-local state dimension + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + local state vector + Array shape: (dim_p) + + py__init_dim_obs_f_pdaf : Callable + Initialize dimension of observation vector + + Callback Parameters + ------------------- + step : int + current time step + + Callback Returns + ---------------- + dim_obs_p : int + dimension of observation vector + + py__obs_op_f_pdaf : Callable + Observation operator + + Callback Parameters + ------------------- + step : int + Current time step + dim_p : int + Size of state vector (local part in case of parallel decomposed state) + dim_obs_p : int + Size of observation vector + state_p : ndarray[np.float64, ndim=1] + Model state vector + Array shape: (dim_p) + + Callback Returns + ---------------- + m_state_p : ndarray[np.float64, ndim=1] + Observed state vector (i.e. the result after applying the observation operator to state_p) + Array shape: (dim_obs_p) + + py__get_obs_f_pdaf : Callable + Initialize observation vector + + Callback Parameters + ------------------- + step : int + Current time step + dim_obs_f : int + Size of the full observation vector + + Callback Returns + ---------------- + observation_f : ndarray[np.float64, ndim=1] + Full vector of synthetic observations (process-local) + Array shape: (dim_obs_f) + + py__prepoststep_pdaf : Callable + User supplied pre/poststep routine + + Callback Parameters + ------------------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Callback Returns + ---------------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + + + Returns + ------- + outflag : int + Status flag + """ + pdaf_cb.collect_state_pdaf = py__collect_state_pdaf + pdaf_cb.init_dim_obs_f_pdaf = py__init_dim_obs_f_pdaf + pdaf_cb.obs_op_f_pdaf = py__obs_op_f_pdaf + pdaf_cb.get_obs_f_pdaf = py__get_obs_f_pdaf + pdaf_cb.prepoststep_pdaf = py__prepoststep_pdaf + cdef int outflag + with nogil: + c__pdafomi_put_state_generate_obs(pdaf_cb.c__collect_state_pdaf, + pdaf_cb.c__init_dim_obs_f_pdaf, + pdaf_cb.c__obs_op_f_pdaf, + pdaf_cb.c__get_obs_f_pdaf, + pdaf_cb.c__prepoststep_pdaf, &outflag) + + return outflag + + diff --git a/pyPDAF/source/src/pyPDAF/PDAFomi/py.typed b/pyPDAF/source/src/pyPDAF/PDAFomi/py.typed new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/pyPDAF/source/src/pyPDAF/PDAFomi/setter.pxd b/pyPDAF/source/src/pyPDAF/PDAFomi/setter.pxd new file mode 100644 index 0000000000000000000000000000000000000000..a1fcb478db92eb5e10d407452987dcb7a459941d --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFomi/setter.pxd @@ -0,0 +1,32 @@ +from pyPDAF.cfi_binding cimport CFI_cdesc_t +cdef extern void c__pdafomi_set_doassim(int* i_obs, + int* doassim) noexcept nogil; + +cdef extern void c__pdafomi_set_disttype(int* i_obs, + int* disttype) noexcept nogil; + +cdef extern void c__pdafomi_set_ncoord(int* i_obs, + int* ncoord) noexcept nogil; + +cdef extern void c__pdafomi_set_obs_err_type(int* i_obs, + int* obs_err_type) noexcept nogil; + +cdef extern void c__pdafomi_set_use_global_obs(int* i_obs, + int* use_global_obs) noexcept nogil; + +cdef extern void c__pdafomi_set_inno_omit(int* i_obs, + double* inno_omit) noexcept nogil; + +cdef extern void c__pdafomi_set_inno_omit_ivar(int* i_obs, + double* inno_omit_ivar) noexcept nogil; + +cdef extern void c__pdafomi_set_id_obs_p(int* i_obs, int* nrows, + int* dim_obs_p, int* id_obs_p) noexcept nogil; + +cdef extern void c__pdafomi_set_icoeff_p(int* i_obs, int* nrows, + int* dim_obs_p, double* icoeff_p) noexcept nogil; + +cdef extern void c__pdafomi_set_domainsize(int* i_obs, int* ncoord, + double* domainsize) noexcept nogil; + +cdef extern void c__pdafomi_set_name(int* i_obs, char* obsname) noexcept nogil; \ No newline at end of file diff --git a/pyPDAF/source/src/pyPDAF/PDAFomi/setter.pyi b/pyPDAF/source/src/pyPDAF/PDAFomi/setter.pyi new file mode 100644 index 0000000000000000000000000000000000000000..f68af1ec6ad55dfeefb506db0efa147d5c306545 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFomi/setter.pyi @@ -0,0 +1,334 @@ +# pylint: disable=unused-argument +"""Stub file for PDAFomi setter module +""" +import numpy as np + +def set_doassim(i_obs: int, doassim: int) -> None: + r"""Setting the `doassim` attribute of `obs_f` + for `i`-th observation type. This property must be + explicitly set for OMI functionality. + + Properties of `obs_f` are typically set in user-supplied function + `py__init_dim_obs_pdaf`. + + This is by default set to 0, which means that + the given type of observation is not assimilated in the DA system. + + Parameters + ---------- + i_obs : int + index of observation types + doassim : int + 0) do not assimilate; + 1) assimilate the observation type + """ + +def set_disttype(i_obs: int, disttype: int) -> None: + r"""Setting the observation localisation distance + calculation method + for `i`-th observation type. This is a mandatory property + for OMI functionality. + + Properties of `obs_f` are typically set in user-supplied function + `py__init_dim_obs_pdaf`. + + `disttype` determines the way the distance + between observation and model grid is calculated in OMI. + To perform distance computation, the observation coordinates should be + given by `ocoord_p` argument + when :func:`pyPDAF.PDAF.omi_gather_obs` is called. + + See also `PDAF distance computation + `_. + + Parameters + ---------- + i_obs : int + index of observations + disttype : int + Type of distance used for localisation + - 0) Cartesian (any units) + - 1) Cartesian periodic (any units) + - 2) Approximation to geographic distance in metres using + latitude and longitude expressed in radians + - 3) Using Haversine formula to compute distance in metres + between two points on the surface of a sphere + - 10) 3D Cartesian distance where horizontal and vertical + distances are treated separately + - 11) 3D Cartesian periodic distance where horizontal and + vertical distances are treated separately + - 12) Same as 2) for horizontal distance but vertical + distance is in units chosen by users where the horizontal + and vertical distances are treated separately + - 13) Same as 3) for horizontal distance but vertical + distance is in units chosen by users where the horizontal + and vertical distances are treated separately + """ + +def set_ncoord(i_obs: int, ncoord: int) -> None: + r"""Setting the number of spatial dimensions of observations + for `i`-th observation type. This is a mandatory property + for OMI functionality. + + Properties of `obs_f` are typically set in user-supplied function + `py__init_dim_obs_pdaf`. + + `ncoord` gives the coordinate dimension of the observation. + This information is used by observation distance computation + for localisation. + For example, `ncoord=2` for 2D observation coordinates. + + Parameters + ---------- + i_obs : int + index of observations + ncoord : int + Dimension of the observation coordinate + """ + +def set_obs_err_type(i_obs: int, obs_err_type: int) -> None: + r"""Setting the type of observation error distribution + for `i`-th observation type. This property is optional + unless a laplacian observation error distribution is used. + + The function is typically used in user-supplied + function `py__init_dim_obs_pdaf`. + + Parameters + ---------- + i_obs : int + index of observations + obs_err_type : int + type of observation error distribution + 0) Gaussian (default) + 1) double exponential (Laplacian) + """ + +def set_use_global_obs(i_obs: int, use_global_obs: int) -> None: + r"""Switch for only use process-local observations + for `i`-th observation type. + + The function is typically used in user-supplied + function `py__init_dim_obs_pdaf`. + + The filters can be performed in parallel + based on the filtering communicator, `comm_filter`. + This is typically the case for the domain-localised filters, + e.g., LESTK, LETKF, LSEIK, LNETF. + In this case, observation vectors are stored in + process-local vectors, `obs_p`. Each local + process (`obs_p`) only stores a section of the full + observation vector. This typically corresponds to the + local domain corresponding to the filtering process, + based on model domain decomposition. + + By default, `use_global_obs=1`. This means that + PDAF-OMI gathers the entire observation vector for all processes. + One can choose to only use process-local observations + for global filters, or within localisation radius for by setting `use_global_obs=0`. + This can save computational cost used for + observation distance calculations. + + However, it needs additional preparations to make + PDAF-OMI aware of the limiting coordinates + of a process sub-domain using + :func:`pyPDAF.PDAFomi.set_domain_limits` or + :func:`pyPDAF.PDAFomi.set_domain_limits_unstruc`. + + + See Also + -------- + https://pdaf.awi.de/trac/wiki/OMI_use_global_obs + + Parameters + ---------- + i_obs : int + index of observations + use_global_obs : int + Swith to use global observations or not + 0) Using process-local observations; + 1) using cross-process observations (default) + """ + +def set_inno_omit(i_obs: int, inno_omit: float) -> None: + r"""Setting innovation threshold for removing observation + outliers. By default, no observations are omitted. + + This function is typically used in user-supplied + function :func:`py__init_dim_obs_pdaf`. + + The observation omission is only activated when it is > 0.0. + PDAF will omit observations where their squared + the innovation of the ensemble mean is larger than + the product of `inno_omit` and observation error variance. + + The observations are omitted by setting a very large + observation error variance, i.e., a very small + inverse of the observation error variance, `inno_omit_ivar`. + This can be set by :func:`pyPDAF.PDAF.omi_set_inno_omit_ivar`. + + Parameters + ---------- + i_obs : int + index of observations + inno_omit : float + Threshold of innovation to be omitted + """ + +def set_inno_omit_ivar(i_obs: int, inno_omit_ivar: float) -> None: + r"""Setting the inverse of observation error variance for + omitted observations. + + This should be set to a very small value relative to + assimilated observations. By default, it is set to `1e-12`. + + This function is typically used in user-supplied function + :func:`py__init_dim_obs_pdaf`. + + Parameters + ---------- + i_obs : int + index of observations + inno_omit_ivar : float + Inverse of observation variance for omiited observations + """ + +def set_id_obs_p(i_obs: int, nrows: int, dim_obs_p: int, id_obs_p: np.ndarray) -> None: + r"""Setting the `id_obs_p` attribute of `obs_f` + for `i`-th observation type. This is a mandatory property + for OMI functionality. + + The function is typically used in user-supplied + function `py__init_dim_obs_pdaf`. + + Here, `id_obs_p(nrows, dim_obs_p)` is a 2D array of integers. + The value of `nrows` depends on the observation operator + used for an observation. + + Examples: + + - `nrows=1`: observations are located on model grid point. + In this case, + `id_obs_p` stores the index of the state vector + (starting from 1) corresponds to the observations, + e.g. `id_obs_p[0, j] = i` means that the location + and variable of the `i`-th element of the state vector + is the same as the `j`-th observation. + + - `nrows=4`: each observation corresponds to + 4 indices of elements in the state vector. + In this case, + the location of these elements is used to perform bi-linear interpolation + from model grid to observation location. + For interpolation, this information is used in the + :func:`pyPDAF.PDAF.omi_obs_op_interp_lin` functions. + This information can also be used to + perform a state vector averaging operator as + observation operator in :func:`pyPDAF.PDAFomi.obs_op_gridavg` When interpolation is needed, + the weighting of the interpolation is done + in the :func:`pyPDAF.PDAFomi.get_interp_coeff_lin`, + :func:`pyPDAF.PDAFomi.get_interp_coeff_lin1D`, + and :func:`pyPDAF.PDAFomi.get_interp_coeff_tri` functions. + The details of interpolation setup can be found at + `PDAF wiki page + `_. + + + Parameters + ---------- + i_obs : int + index of observations + nrows : int + number of state vector used to interpolate + to one observation location + dim_obs_p : int + dimension of PE local obs vector + id_obs_p : ndarray[tuple[nrows, dim_obs_p, ...], np.intc] + indice corresponds to observations in the state vector + The 1st-th dimension nrows is number of values to be averaged or used for interpolation + The 2nd-th dimension dim_obs_p is dimension of PE local obs + """ + +def set_icoeff_p(i_obs: int, nrows: int, dim_obs_p: int, icoeff_p: np.ndarray) -> None: + r"""Setting the observation interpolation coefficient + for `i`-th observation type. This property is optional + unless interpolations needed in observation operators + operator. + + The function is typically used in user-supplied + function `py__init_dim_obs_pdaf`. + + `icoeff_p(nrows, dim_obs_p)` is a 2D array of real number + used to interpolate state vector to point-wise observation grid. + The `nrows` is the number of state vector used to interpolate + to one observation location. + + A suite of functions are provided to obtain these coefficients, + which depend on `obs_f` attribute of `id_obs_p` and + observation coordinates. + + See also :func:`pyPDAF.PDAF.set_id_obs_p`: + - :func:`pyPDAF.PDAFomi.get_interp_coeff_lin1D` + 1D interpolation coefficient + - :func:`pyPDAF.PDAFomi.get_interp_coeff_lin` + linear interpolation coefficient for 1, 2 and 3D rectangular grids + - :func:`pyPDAF.PDAFomi.get_interp_coeff_tri` + 2D linear interpolation for triangular grids + + See also `PDAF documentation for OMI interpolations + `_. + + Parameters + ---------- + i_obs : int + index of observations + nrows : int + number of state vector used to interpolate + to one observation location + dim_obs_p : int + dimension of PE local obs vector + icoeff_p : ndarray[tuple[nrows, dim_obs_p, ...], np.float64] + weighting coefficients for interpolations + The 1st-th dimension nrows is number of state vector used to interpolate + to one observation location + The 2nd-th dimension dim_obs_p is dimension of PE local obs + """ + +def set_domainsize(i_obs: int, ncoord: int, domainsize: np.ndarray) -> None: + r"""Setting the domain periodicity + attribute of `obs_f` + for `i`-th observation type. This property is optional + unless localisation is used. + + The function is typically used in user-supplied + function `py__init_dim_obs_pdaf`. + + `domainsize(ncoord)` specifies the size of the domain + in each spatial dimension. + This information is used to compute the Cartesian disance + with periodic boundary. That is `disttype = 1 or 11` + Domain size must be positive. + If the value of one dimension is `<=0`, + no periodicity is assumed in that dimension. + + Parameters + ---------- + i_obs : int + index of observations + ncoord: int + Number of spatial dimensions + domainsize : ndarray[tuple[ncoord, ...], np.float64] + Size of the domain in each dimension + The array dimension `ncoord` is state dimension + """ + +def set_name(i_obs: int, obsname: str) -> None: + """Set a name for given observation type + + Parameters + ---------- + i_obs : int + index of observation type + obsname : str + name of observation type + """ diff --git a/pyPDAF/source/src/pyPDAF/PDAFomi/setter.pyx b/pyPDAF/source/src/pyPDAF/PDAFomi/setter.pyx new file mode 100644 index 0000000000000000000000000000000000000000..8d61e9725f17f07b371265e846ad96e83e85c1a8 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/PDAFomi/setter.pyx @@ -0,0 +1,395 @@ +import sys +import numpy as np +cimport numpy as cnp +from pyPDAF cimport pdaf_c_cb_interface as pdaf_cb +from pyPDAF.cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish +from pyPDAF.cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int +from pyPDAF.cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3 + +def set_doassim(int i_obs, int doassim): + r"""set_doassim(i_obs: int, doassim: int) -> None + + Setting the `doassim` attribute of `obs_f` + for `i`-th observation type. This property must be + explicitly set for OMI functionality. + + Properties of `obs_f` are typically set in user-supplied function + `py__init_dim_obs_pdaf`. + + This is by default set to 0, which means that + the given type of observation is not assimilated in the DA system. + + Parameters + ---------- + i_obs : int + index of observation types + doassim : int + 0) do not assimilate; + 1) assimilate the observation type + """ + with nogil: + c__pdafomi_set_doassim(&i_obs, &doassim) + +def set_disttype(int i_obs, int disttype): + r"""set_disttype(i_obs: int, disttype: int) -> None + + Setting the observation localisation distance + calculation method + for `i`-th observation type. This is a mandatory property + for OMI functionality. + + Properties of `obs_f` are typically set in user-supplied function + `py__init_dim_obs_pdaf`. + + `disttype` determines the way the distance + between observation and model grid is calculated in OMI. + To perform distance computation, the observation coordinatesshould be given by `ocoord_p` argument + when :func:`pyPDAF.PDAF.omi_gather_obs` is called. + + See also `PDAF distance computation `_. + + Parameters + ---------- + i_obs : int + index of observations + disttype : int + Type of distance used for localisation + - 0) Cartesian (any units) + - 1) Cartesian periodic (any units) + - 2) Approximation to geographic distance in metres using + latitude and longitude expressed in radians + - 3) Using Haversine formula to compute distance in metres + between two points on the surface of a sphere + - 10) 3D Cartesian distance where horizontal and vertical + distances are treated separately + - 11) 3D Cartesian periodic distance where horizontal and + vertical distances are treated separately + - 12) Same as 2) for horizontal distance but vertical + distance is in units chosen by users where the horizontal + and vertical distances are treated separately + - 13) Same as 3) for horizontal distance but vertical + distance is in units chosen by users where the horizontal + and vertical distances are treated separately + """ + with nogil: + c__pdafomi_set_disttype(&i_obs, &disttype) + + + +def set_ncoord(int i_obs, int ncoord): + r"""set_ncoord(i_obs: int, ncoord: int) -> None + + Setting the number of spatial dimensions of observations + for `i`-th observation type. This is a mandatory property + for OMI functionality. + + Properties of `obs_f` are typically set in user-supplied function + `py__init_dim_obs_pdaf`. + + `ncoord` gives the coordinate dimension of the observation. + This information is used by observation distance computation + for localisation. + For example, `ncoord=2` for 2D observation coordinates. + + Parameters + ---------- + i_obs : int + index of observations + ncoord : int + Dimension of the observation coordinate + """ + with nogil: + c__pdafomi_set_ncoord(&i_obs, &ncoord) + + + +def set_obs_err_type(int i_obs, int obs_err_type): + r"""set_obs_err_type(i_obs: int, obs_err_type: int) -> None + + Setting the type of observation error distribution + for `i`-th observation type. This property is optional + unless a laplacian observation error distribution is used. + + The function is typically used in user-supplied + function `py__init_dim_obs_pdaf`. + + Parameters + ---------- + i_obs : int + index of observations + obs_err_type : int + type of observation error distribution + 0) Gaussian (default) + 1) double exponential (Laplacian) + """ + with nogil: + c__pdafomi_set_obs_err_type(&i_obs, &obs_err_type) + + + +def set_use_global_obs(int i_obs, int use_global_obs): + r"""set_use_global_obs(i_obs: int, use_global_obs: int) -> None + + Switch for only use process-local observations + for `i`-th observation type. + + The function is typically used in user-supplied + function `py__init_dim_obs_pdaf`. + + The filters can be performed in parallel + based on the filtering communicator, `comm_filter`. + This is typically the case for the domain-localised filters, + e.g., LESTK, LETKF, LSEIK, LNETF. + In this case, observation vectors are stored in + process-local vectors, `obs_p`. Each local + process (`obs_p`) only stores a section of the full + observation vector. This typically corresponds to the + local domain corresponding to the filtering process, + based on model domain decomposition. + + By default, `use_global_obs=1`. This means that + PDAF-OMI gathers the entire observation vector for all processes. + One can choose to only use process-local observations + for global filters, or within localisation radius for by setting `use_global_obs=0`. + This can save computational cost used for + observation distance calculations. + + However, it needs additional preparations to make + PDAF-OMI aware of the limiting coordinates + of a process sub-domain using + :func:`pyPDAF.PDAFomi.set_domain_limits` or + :func:`pyPDAF.PDAFomi.set_domain_limits_unstruc`. + + + See Also + -------- + https://pdaf.awi.de/trac/wiki/OMI_use_global_obs + + Parameters + ---------- + i_obs : int + index of observations + use_global_obs : int + Swith to use global observations or not + 0) Using process-local observations; + 1) using cross-process observations (default) + """ + with nogil: + c__pdafomi_set_use_global_obs(&i_obs, &use_global_obs) + + + +def set_inno_omit(int i_obs, double inno_omit): + r"""set_inno_omit(i_obs: int, inno_omit: float) -> None + + Setting innovation threshold for removing observation + outliers. By default, no observations are omitted. + + This function is typically used in user-supplied + function :func:`py__init_dim_obs_pdaf`. + + The observation omission is only activated when it is > 0.0. + PDAF will omit observations where their squared + the innovation of the ensemble mean is larger than + the product of `inno_omit` and observation error variance. + + The observations are omitted by setting a very large + observation error variance, i.e., a very small + inverse of the observation error variance, `inno_omit_ivar`. + This can be set by :func:`pyPDAF.PDAF.omi_set_inno_omit_ivar`. + + Parameters + ---------- + i_obs : int + index of observations + inno_omit : float + Threshold of innovation to be omitted + """ + with nogil: + c__pdafomi_set_inno_omit(&i_obs, &inno_omit) + + + +def set_inno_omit_ivar(int i_obs, double inno_omit_ivar): + r"""set_inno_omit_ivar(i_obs: int, inno_omit_ivar: float) -> None + + Setting the inverse of observation error variance for + omitted observations. + + This should be set to a very small value relative to + assimilated observations. By default, it is set to `1e-12`. + + This function is typically used in user-supplied function + :func:`py__init_dim_obs_pdaf`. + + Parameters + ---------- + i_obs : int + index of observations + inno_omit_ivar : float + Inverse of observation variance for omiited observations + """ + with nogil: + c__pdafomi_set_inno_omit_ivar(&i_obs, &inno_omit_ivar) + + + +def set_id_obs_p(int i_obs, int nrows, int dim_obs_p, int [::1,:] id_obs_p): + r"""set_id_obs_p(i_obs: int, nrows: int, dim_obs_p: int, id_obs_p: np.ndarray) -> None + + Setting the `id_obs_p` attribute of `obs_f` + for `i`-th observation type. This is a mandatory property + for OMI functionality. + + The function is typically used in user-supplied + function `py__init_dim_obs_pdaf`. + + Here, `id_obs_p(nrows, dim_obs_p)` is a 2D array of integers. + The value of `nrows` depends on the observation operator + used for an observation. + + Examples: + + - `nrows=1`: observations are located on model grid point. + In this case, + `id_obs_p` stores the index of the state vector + (starting from 1) corresponds to the observations, + e.g. `id_obs_p[0, j] = i` means that the location + and variable of the `i`-th element of the state vector + is the same as the `j`-th observation. + + - `nrows=4`: each observation corresponds to + 4 indices of elements in the state vector. + In this case, + the location of these elements is used to perform bi-linear interpolation + from model grid to observation location. + For interpolation, this information is used in the + :func:`pyPDAF.PDAF.omi_obs_op_interp_lin` functions. + This information can also be used to + perform a state vector averaging operator as + observation operator in :func:`pyPDAF.PDAFomi.obs_op_gridavg` When interpolation is needed, + the weighting of the interpolation is done + in the :func:`pyPDAF.PDAFomi.get_interp_coeff_lin`, + :func:`pyPDAF.PDAFomi.get_interp_coeff_lin1D`, + and :func:`pyPDAF.PDAFomi.get_interp_coeff_tri` functions. + The details of interpolation setup can be found at + `PDAF wiki page `_. + + + Parameters + ---------- + i_obs : int + index of observations + nrows : int + number of state vector used to interpolate + to one observation location + dim_obs_p : int + dimension of PE local obs vector + id_obs_p : ndarray[tuple[nrows, dim_obs_p, ...], np.intc] + indice corresponds to observations in the state vector + The 1st-th dimension nrows is number of values to be averaged or used for interpolation + The 2nd-th dimension dim_obs_p is dimension of PE local obs + """ + with nogil: + c__pdafomi_set_id_obs_p(&i_obs, &nrows, &dim_obs_p, &id_obs_p[0,0]) + + + +def set_icoeff_p(int i_obs, int nrows, int dim_obs_p, + double [::1,:] icoeff_p): + r"""set_icoeff_p(i_obs: int, nrows: int, dim_obs_p: int, icoeff_p: np.ndarray) -> None + + Setting the observation interpolation coefficient + for `i`-th observation type. This property is optional + unless interpolations needed in observation operators + operator. + + The function is typically used in user-supplied + function `py__init_dim_obs_pdaf`. + + `icoeff_p(nrows, dim_obs_p)` is a 2D array of real number + used to interpolate state vector to point-wise observation grid. + The `nrows` is the number of state vector used to interpolate + to one observation location. + + A suite of functions are provided to obtain these coefficients, + which depend on `obs_f` attribute of `id_obs_p` and + observation coordinates. + + See also :func:`pyPDAF.PDAF.set_id_obs_p`: + - :func:`pyPDAF.PDAFomi.get_interp_coeff_lin1D` + 1D interpolation coefficient + - :func:`pyPDAF.PDAFomi.get_interp_coeff_lin` + linear interpolation coefficient for 1, 2 and 3D rectangular grids + - :func:`pyPDAF.PDAFomi.get_interp_coeff_tri` + 2D linear interpolation for triangular grids + + See also `PDAF documentation for OMI interpolations `_. + + Parameters + ---------- + i_obs : int + index of observations + nrows : int + number of state vector used to interpolate + to one observation location + dim_obs_p : int + dimension of PE local obs vector + icoeff_p : ndarray[tuple[nrows, dim_obs_p, ...], np.float64] + weighting coefficients for interpolations + The 1st-th dimension nrows is number of state vector used to interpolate + to one observation location + The 2nd-th dimension dim_obs_p is dimension of PE local obs + """ + with nogil: + c__pdafomi_set_icoeff_p(&i_obs, &nrows, &dim_obs_p, &icoeff_p[0,0]) + + + +def set_domainsize(int i_obs, int ncoord, double [::1] domainsize): + r"""set_domainsize(i_obs: int, ncoord: int, domainsize: np.ndarray) -> None + + Setting the domain periodicity attribute of `obs_f` + for `i`-th observation type. This property is optional + unless localisation is used. + + The function is typically used in user-supplied + function `py__init_dim_obs_pdaf`. + + `domainsize(ncoord)` specifies the size of the domain + in each spatial dimension. + This information is used to compute the Cartesian disance + with periodic boundary. That is `disttype = 1 or 11` + Domain size must be positive. + If the value of one dimension is `<=0`, + no periodicity is assumed in that dimension. + + Parameters + ---------- + i_obs : int + index of observations + ncoord: int + Number of spatial dimensions + domainsize : ndarray[tuple[ncoord, ...], np.float64] + Size of the domain in each dimension + The array dimension `ncoord` is state dimension + """ + with nogil: + c__pdafomi_set_domainsize(&i_obs, &ncoord, &domainsize[0]) + +def set_name(int i_obs, str obsname): + """set_name(i_obs: int, obsname: str) -> None + + Set a name for given observation type + + Parameters + ---------- + i_obs : int + index of observation type + obsname : str + name of observation type + """ + obsname_byte = obsname.encode('UTF-8') + cdef char* obsname_ptr = obsname_byte + with nogil: + c__pdafomi_set_name(&i_obs, obsname_ptr) diff --git a/pyPDAF/source/src/pyPDAF/README.md b/pyPDAF/source/src/pyPDAF/README.md new file mode 100644 index 0000000000000000000000000000000000000000..34676d06769ab0787d7ec7b05341b8d243c5e949 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/README.md @@ -0,0 +1,3 @@ +## pyPDAF + +This package is a Python interface for the Fortran-written PDAF data assimilation package. diff --git a/pyPDAF/source/src/pyPDAF/__init__.py b/pyPDAF/source/src/pyPDAF/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8f0f1cd35ed834ca0669b3ed4f3cc186d439b5a7 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/__init__.py @@ -0,0 +1,95 @@ +# pylint: disable=wrong-import-position +"""Python interface to the PDAF library.""" +import os +import sys +from traceback import print_exception + +import mpi4py +mpi4py.rc.initialize = False + +def _append_to_sharedlib_load_path(): + """Ensure the shared libraries in this package can be loaded on Windows. + + Windows lacks a concept equivalent to RPATH: Python extension modules + cannot find DLLs installed outside the DLL search path. This function + ensures that the location of the shared libraries distributed inside this + Python package is in the DLL search path of the process. + + The Windows DLL search path includes the path to the object attempting + to load the DLL: it needs to be augmented only when the Python extension + modules and the DLLs they require are installed in separate directories. + Cygwin does not have the same default library search path: all locations + where the shared libraries are installed need to be added to the search + path. + + This function is very similar to the snippet inserted into the main + ``__init__.py`` of a package by ``delvewheel`` when it vendors external + shared libraries. + + .. note:: + + `os.add_dll_directory` is only available for Python 3.8 and later, and + in the Conda ``python`` packages it works as advertised only for + version 3.10 and later. For older Python versions, pre-loading the DLLs + with `ctypes.WinDLL` may be preferred. + """ + basedir = os.path.dirname(__file__) + if os.name == 'nt': + os.add_dll_directory(basedir) + elif sys.platform == 'cygwin': + os.environ['PATH'] = os.pathsep.join((os.environ['PATH'], basedir)) + +# Global error handler +def global_except_hook(exctype, value, traceback): + """Global error handler that aborts MPI jobs on uncaught exceptions.""" + if mpi4py.MPI.Is_initialized(): + try: + sys.stderr.write('Uncaught exception was detected on rank' + f' {mpi4py.MPI.COMM_WORLD.Get_rank()}.\n') + print_exception(exctype, value, traceback) + sys.stderr.write("\n") + sys.stderr.flush() + finally: + try: + mpi4py.MPI.COMM_WORLD.Abort(1) + except Exception as e: + sys.stderr.write('MPI Abort failed, this process will hang.\n') + sys.stderr.flush() + raise e + else: + sys.__excepthook__(exctype, value, traceback) + + +sys.excepthook = global_except_hook + +_append_to_sharedlib_load_path() + +from pyPDAF.PDAF3 import init, init_forecast, set_parallel +from pyPDAF.PDAF3 import assimilate, assim_offline +from pyPDAF.PDAF3 import assimilate_local_nondiagr, assimilate_global_nondiagr, \ + assimilate_lnetf_nondiagr, assimilate_lknetf_nondiagr, \ + assimilate_enkf_nondiagr, assimilate_nonlin_nondiagr +from pyPDAF.PDAF3 import assim_offline_local_nondiagr, \ + assim_offline_global_nondiagr, \ + assim_offline_lnetf_nondiagr, \ + assim_offline_lknetf_nondiagr, \ + assim_offline_enkf_nondiagr, \ + assim_offline_lenkf_nondiagr, \ + assim_offline_nonlin_nondiagr +from pyPDAF.PDAF3 import assimilate_3dvar_all, assim_offline_3dvar_all +from pyPDAF.PDAF3 import assimilate_3dvar_nondiagr, assimilate_en3dvar_estkf_nondiagr, \ + assimilate_en3dvar_lestkf_nondiagr, \ + assimilate_hyb3dvar_estkf_nondiagr, \ + assimilate_hyb3dvar_lestkf_nondiagr +from pyPDAF.PDAF3 import assim_offline_3dvar_nondiagr, assim_offline_en3dvar_estkf_nondiagr, \ + assim_offline_en3dvar_lestkf_nondiagr, \ + assim_offline_hyb3dvar_estkf_nondiagr, \ + assim_offline_hyb3dvar_lestkf_nondiagr +from pyPDAF.PDAF3 import generate_obs, generate_obs_offline +from pyPDAF.PDAF import get_fcst_info, deallocate + +from . import PDAF +from . import PDAFomi +from . import PDAF3 +from . import PDAFlocal +from . import PDAFlocalomi diff --git a/pyPDAF/source/src/pyPDAF/__pycache__/__init__.cpython-310.pyc b/pyPDAF/source/src/pyPDAF/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3357d98beaf9650e7e4031b50754df6f38bdab70 Binary files /dev/null and b/pyPDAF/source/src/pyPDAF/__pycache__/__init__.cpython-310.pyc differ diff --git a/pyPDAF/source/src/pyPDAF/cfi_binding.pxd b/pyPDAF/source/src/pyPDAF/cfi_binding.pxd new file mode 100644 index 0000000000000000000000000000000000000000..6d49ae2d008d0b8a28f7b0a120d246a4c1825293 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/cfi_binding.pxd @@ -0,0 +1,38 @@ +from libc.stdint cimport int8_t, int16_t +from libc.stddef cimport ptrdiff_t + +cdef extern from "ISO_Fortran_binding.h": + """ + typedef CFI_CDESC_T(1) CFI_cdesc_rank1; + typedef CFI_CDESC_T(2) CFI_cdesc_rank2; + typedef CFI_CDESC_T(3) CFI_cdesc_rank3; + """ + ctypedef ptrdiff_t CFI_index_t; + ctypedef int8_t CFI_rank_t; + ctypedef int8_t CFI_attribute_t; + ctypedef int16_t CFI_type_t; + + ctypedef struct CFI_dim_t: + CFI_index_t extent; + + ctypedef struct CFI_cdesc_t: + void *base_addr; + CFI_rank_t rank; + CFI_attribute_t attribute; + CFI_dim_t* dim; + + ctypedef CFI_cdesc_t CFI_cdesc_rank1; + ctypedef CFI_cdesc_t CFI_cdesc_rank2; + ctypedef CFI_cdesc_t CFI_cdesc_rank3; + + cdef int CFI_attribute_pointer; + cdef int CFI_attribute_allocatable; + cdef int CFI_attribute_other; + + cdef CFI_type_t CFI_type_double; + cdef CFI_type_t CFI_type_int; + + cdef extern void *CFI_address (const CFI_cdesc_t *, const CFI_index_t*) noexcept nogil; + cdef extern int CFI_establish(CFI_cdesc_t *, void *, CFI_attribute_t, + CFI_type_t, size_t, CFI_rank_t, const CFI_index_t*) noexcept nogil; + diff --git a/pyPDAF/source/src/pyPDAF/pdaf_c_cb_interface.pxd b/pyPDAF/source/src/pyPDAF/pdaf_c_cb_interface.pxd new file mode 100644 index 0000000000000000000000000000000000000000..c72bb67d36e83bd22c86d5cb25537cc08e1eb3d6 --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/pdaf_c_cb_interface.pxd @@ -0,0 +1,155 @@ +cdef void c__add_obs_err_pdaf(int* step, int* dim_obs_p, + double* c_p) noexcept nogil; +cdef void* add_obs_err_pdaf = NULL; + +cdef void c__init_ens_pdaf(int* filtertype, int* dim_p, int* dim_ens, + double* state_p, double* uinv, double* ens_p, int* flag) noexcept nogil; +cdef void* init_ens_pdaf = NULL; + +cdef void c__next_observation_pdaf(int* stepnow, int* nsteps, int* doexit, + double* time) noexcept nogil; +cdef void* next_observation_pdaf = NULL; + +cdef void c__collect_state_pdaf(int* dim_p, double* state_p) noexcept nogil; +cdef void* collect_state_pdaf = NULL; + +cdef void c__distribute_state_pdaf(int* dim_p, double* state_p) noexcept nogil; +cdef void* distribute_state_pdaf = NULL; + +cdef void c__prepoststep_pdaf(int* step, int* dim_p, int* dim_ens, + int* dim_ens_l, int* dim_obs_p, double* state_p, double* uinv, + double* ens_p, int* flag) noexcept nogil; +cdef void* prepoststep_pdaf = NULL; + +cdef void c__init_dim_obs_pdaf(int* step, int* dim_obs_p) noexcept nogil; +cdef void* init_dim_obs_pdaf = NULL; + +cdef void c__init_dim_obs_f_pdaf(int* step, int* dim_obs_p) noexcept nogil; +cdef void* init_dim_obs_f_pdaf = NULL; + +cdef void c__init_obs_pdaf(int* step, int* dim_obs_p, + double* observation_p) noexcept nogil; +cdef void* init_obs_pdaf = NULL; + +cdef void c__init_obs_covar_pdaf(int* step, int* dim_obs, int* dim_obs_p, + double* covar, double* obs_p, bint* isdiag) noexcept nogil; +cdef void* init_obs_covar_pdaf = NULL; + +cdef void c__init_obsvar_pdaf(int* step, int* dim_obs_p, double* obs_p, + double* meanvar) noexcept nogil; +cdef void* init_obsvar_pdaf = NULL; + +cdef void c__init_obsvars_pdaf(int* step, int* dim_obs_f, + double* var_f) noexcept nogil; +cdef void* init_obsvars_pdaf = NULL; + +cdef void c__prodrinva_pdaf(int* step, int* dim_obs_p, int* rank, + double* obs_p, double* a_p, double* c_p) noexcept nogil; +cdef void* prodrinva_pdaf = NULL; + +cdef void c__obs_op_pdaf(int* step, int* dim_p, int* dim_obs_p, + double* state_p, double* m_state_p) noexcept nogil; +cdef void* obs_op_pdaf = NULL; + +cdef void c__obs_op_f_pdaf(int* step, int* dim_p, int* dim_obs_p, + double* state_p, double* m_state_p) noexcept nogil; +cdef void* obs_op_f_pdaf = NULL; + +cdef void c__g2l_obs_pdaf(int* domain_p, int* step, int* dim_obs_f, + int* dim_obs_l, int* mstate_f, int* mstate_l) noexcept nogil; +cdef void* g2l_obs_pdaf = NULL; + +cdef void c__g2l_state_pdaf(int* step, int* domain_p, int* dim_p, + double* state_p, int* dim_l, double* state_l) noexcept nogil; +cdef void* g2l_state_pdaf = NULL; + +cdef void c__init_dim_l_pdaf(int* step, int* domain_p, + int* dim_l) noexcept nogil; +cdef void* init_dim_l_pdaf = NULL; + +cdef void c__init_dim_obs_l_pdaf(int* domain_p, int* step, int* dim_obs_f, + int* dim_obs_l) noexcept nogil; +cdef void* init_dim_obs_l_pdaf = NULL; + +cdef void c__init_n_domains_p_pdaf(int* step, int* n_domains_p) noexcept nogil; +cdef void* init_n_domains_p_pdaf = NULL; + +cdef void c__init_obs_f_pdaf(int* step, int* dim_obs_f, + double* observation_f) noexcept nogil; +cdef void* init_obs_f_pdaf = NULL; + +cdef void c__init_obs_l_pdaf(int* domain_p, int* step, int* dim_obs_l, + double* observation_l) noexcept nogil; +cdef void* init_obs_l_pdaf = NULL; + +cdef void c__init_obsvar_l_pdaf(int* domain_p, int* step, int* dim_obs_l, + double* obs_l, int* dim_obs_p, double* meanvar_l) noexcept nogil; +cdef void* init_obsvar_l_pdaf = NULL; + +cdef void c__init_obserr_f_pdaf(int* step, int* dim_obs_f, double* obs_f, + double* obserr_f) noexcept nogil; +cdef void* init_obserr_f_pdaf = NULL; + +cdef void c__l2g_state_pdaf(int* step, int* domain_p, int* dim_l, + double* state_l, int* dim_p, double* state_p) noexcept nogil; +cdef void* l2g_state_pdaf = NULL; + +cdef void c__prodrinva_l_pdaf(int* domain_p, int* step, int* dim_obs_l, + int* rank, double* obs_l, double* a_l, double* c_l) noexcept nogil; +cdef void* prodrinva_l_pdaf = NULL; + +cdef void c__localize_covar_pdaf(int* dim_p, int* dim_obs, double* hp_p, + double* hph) noexcept nogil; +cdef void* localize_covar_pdaf = NULL; + +cdef void c__localize_covar_serial_pdaf(int* iobs, int* dim_p, + int* dim_obs, double* hp_p, double* hxy_p) noexcept nogil; +cdef void* localize_covar_serial_pdaf = NULL; + +cdef void c__likelihood_pdaf(int* step, int* dim_obs_p, double* obs_p, + double* resid, double* likely) noexcept nogil; +cdef void* likelihood_pdaf = NULL; + +cdef void c__likelihood_l_pdaf(int* domain_p, int* step, int* dim_obs_l, + double* obs_l, double* resid_l, double* likely_l) noexcept nogil; +cdef void* likelihood_l_pdaf = NULL; + +cdef void c__get_obs_f_pdaf(int* step, int* dim_obs_f, + double* observation_f) noexcept nogil; +cdef void* get_obs_f_pdaf = NULL; + +cdef void c__cvt_adj_ens_pdaf(int* iter, int* dim_p, int* dim_ens, + int* dim_cv_ens_p, double* ens_p, double* vcv_p, + double* cv_p) noexcept nogil; +cdef void* cvt_adj_ens_pdaf = NULL; + +cdef void c__cvt_adj_pdaf(int* iter, int* dim_p, int* dim_cvec, + double* vcv_p, double* cv_p) noexcept nogil; +cdef void* cvt_adj_pdaf = NULL; + +cdef void c__cvt_pdaf(int* iter, int* dim_p, int* dim_cvec, double* cv_p, + double* vv_p) noexcept nogil; +cdef void* cvt_pdaf = NULL; + +cdef void c__cvt_ens_pdaf(int* iter, int* dim_p, int* dim_ens, + int* dim_cvec_ens, double* ens_p, double* v_p, double* vv_p) noexcept nogil; +cdef void* cvt_ens_pdaf = NULL; + +cdef void c__obs_op_adj_pdaf(int* step, int* dim_p, int* dim_obs_p, + double* m_state_p, double* state_p) noexcept nogil; +cdef void* obs_op_adj_pdaf = NULL; + +cdef void c__obs_op_lin_pdaf(int* step, int* dim_p, int* dim_obs_p, + double* state_p, double* m_state_p) noexcept nogil; +cdef void* obs_op_lin_pdaf = NULL; + +cdef void c__likelihood_hyb_l_pdaf(int* domain_p, int* step, + int* dim_obs_l, double* obs_l, double* resid_l, double* gamma, + double* likely_l) noexcept nogil; +cdef void* likelihood_hyb_l_pdaf = NULL; + +cdef void c__prodrinva_hyb_l_pdaf(int* domain_p, int* step, int* dim_obs_l, + int* dim_ens, double* obs_l, double* gamma, double* a_l, + double* c_l) noexcept nogil; +cdef void* prodrinva_hyb_l_pdaf = NULL; + diff --git a/pyPDAF/source/src/pyPDAF/pdaf_c_cb_interface.pyi b/pyPDAF/source/src/pyPDAF/pdaf_c_cb_interface.pyi new file mode 100644 index 0000000000000000000000000000000000000000..2d57a0fae5ab836308eaaf5c371c9b04d9b041ee --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/pdaf_c_cb_interface.pyi @@ -0,0 +1,1165 @@ +# pylint: disable=unused-argument, too-many-lines +"""Stub file for user-supplied functions. +""" +from typing import Tuple +import numpy as np + +def add_obs_err_pdaf(step: int, dim_obs_p: int, c_p: np.ndarray) -> np.ndarray: + """Add the observation error covariance matrix to the matrix C. + + The input matrix is the projection of the ensemble + covariance matrix onto the observation space that is computed + during the analysis step of the stochastic EnKF. That is, HPH.T. + The function returns HPH.T + R. + + The operation is for the global observation space. + Thus, it is independent of whether the filter is executed with or + without parallelization. + + Parameters + ---------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + C_p : ndarray[np.float64, ndim=2] + Matrix to which the observation error covariance matrix is added + shape: (dim_obs_p, dim_obs_p) + + Returns + ------- + C_p : ndarray[np.float64, ndim=2] + Matrix with added obs error covariance, i.e., HPH.T + R + shape: (dim_obs_p, dim_obs_p) + """ + +def init_ens_pdaf(filtertype: int, dim_p: int, dim_ens: int, state_p: np.ndarray, + uinv: np.ndarray, ens_p: np.ndarray, flag: int + ) -> Tuple[np.ndarray, np.ndarray, np.ndarray, int]: + """Fill the ensemble array that is provided by PDAF with an initial ensemble of model states. + + This function is called by :func:`pyPDAF.PDAF.init`. The initialised + ensemble array will be distributed to model by :func:`pyPDAF.PDAF.init_forecast`. + + Parameters + ---------- + filtertype : int + filter type given in PDAF_init + dim_p : int + PE-local state dimension given by PDAF_init + dim_ens : int + number of ensemble members + state_p : ndarray[np.float64, ndim=1] + PE-local model state + This array must be filled with the initial + state of the model for SEEK, but it is not + used for ensemble-based filters. + One can still make use of this array within + this function. + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + This array is the inverse of matrix + formed by right singular vectors of error + covariance matrix of ensemble perturbations. + This array has to be filled in SEEK, but it is + not used for ensemble-based filters. + Nevertheless, one can still make use of this + array within this function e.g., + for generating an initial ensemble perturbation + from a given covariance matrix. + Dimension of this array is determined by the + filter type. + * (dim_ens, dim_ens) for (L)ETKF, (L)NETF, (L)KNETF, and SEEK + * (dim_ens - 1, dim_ens - 1) for (L)SEIK, (L)ESTKF, and 3DVar using ensemble + * (1, 1) for (L)EnKF, particle filters and gen_obs + Array shape: (dim_ens - 1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + This array must be filled with the initial + state of the model for SEEK, but it is not + used for ensemble-based filters. + One can still make use of this array within + this function. + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + This array is the inverse of matrix + formed by right singular vectors of error + covariance matrix of ensemble perturbations. + This array has to be filled in SEEK, but it is + not used for ensemble-based filters. + Nevertheless, one can still make use of this + array within this function e.g., + for generating an initial ensemble perturbation + from a given covariance matrix. + Dimension of this array is determined by the + filter type. + * (dim_ens, dim_ens) for (L)ETKF, (L)NETF, (L)KNETF, and SEEK + * (dim_ens - 1, dim_ens - 1) for (L)SEIK, (L)ESTKF, and 3DVar using ensemble + * (1, 1) for (L)EnKF, particle filters and gen_obs + Array shape: (dim_ens - 1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + """ + +def next_observation_pdaf(stepnow: int, nsteps: int, + doexit: int, + time: float +) -> Tuple[int, int, float]: + """Get the number of time steps to be computed in the forecast phase. + + At the beginning of a forecast phase, this is called once by + * :func:`pyPDAF.PDAF.init_forecast` + * :func:`pyPDAF.PDAF3.assimilate_X` + * ... + + Parameters + ---------- + stepnow : int + the current time step given by PDAF + + Returns + ------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + """ + +def collect_state_pdaf( + dim_p: int, + state_p: np.ndarray +) -> np.ndarray: + """Collect state vector from model/any arrays to pdaf arrays + + Parameters + ---------- + dim_p : int + pe-local state dimension + + state_p : ndarray[tuple[dim_p, ...], np.float64] + local state vector + + Returns + ------- + state_p : ndarray[tuple[dim_p, ...], np.float64] + local state vector + """ + +def distribute_state_pdaf( + dim_p: int, + state_p: np.ndarray +) -> np.ndarray: + """Distribute a state vector from pdaf to the model/any arrays + + Parameters + ---------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + """ + +def prepoststep_pdaf( + step: int, + dim_p: int, + dim_ens: int, + dim_ens_l: int, + dim_obs_p: int, + state_p: np.ndarray, + uinv: np.ndarray, + ens_p: np.ndarray, + flag: int +) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: + """Process ensemble before or after DA. + + Parameters + ---------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + """ + +def init_dim_obs_pdaf(step: int, dim_obs_p: int) -> int: + """Determine the size of the vector of observations + + The primary purpose of this function is to + obtain the dimension of the observation vector. + In OMI, in this function, one also sets the properties + of `obs_f`, read the observation vector from + files, setting the observation error variance + when diagonal observation error covariance matrix + is used. The `pyPDAF.PDAF.omi_gather_obs` function + is also called here. + + Furthermore, in this user-supplied function, one also sets the interpolation + coefficients used by observation operators. + + Parameters + ---------- + step : int + Current time step. + dim_obs_p : int + Dimension of the observation vector. + + Returns + ------- + dim_obs_p : int + Dimension of the observation vector. + """ + +def init_dim_obs_f_pdaf(step: int, dim_obs_f: int) -> int: + """Determine the size of the full observations vector + + This function is used with domain localised filters to obtain the dimension of full + observation vector that contains observations outside process-local domains. + The smallest vector only needs observations within localisation radius of the + process-local domain. + + Parameters + ---------- + step : int + Current time step. + dim_obs_f : int + Dimension of the full observation vector. + + Returns + ------- + dim_obs_f : int + Dimension of the full observation vector. + """ + +def init_obs_pdaf(step: int, dim_obs_p: int, observation_p: np.ndarray) -> np.ndarray: + """Provide the observation vector for the current time step. + + Parameters + ---------- + step : int + Current time step. + dim_obs_p : int + Dimension of the observation vector. + observation_p : ndarray[np.float64, ndim=1] + Observation vector. + + Returns + ------- + observation_p : ndarray[np.float64, ndim=1] + Filled observation vector. + """ + +def init_obs_f_pdaf(step: int, dim_obs_f: int, observation_f: np.ndarray) -> np.ndarray: + """Provide the observation vector for the current time step. + + This function is used with domain localised filters to obtain a full + observation vector that contains observations outside process-local domains. + The smallest vector only needs observations within localisation radius of the + process-local domain. + + Parameters + ---------- + step : int + Current time step. + dim_obs_f : int + Dimension of the observation vector. + observation_f : ndarray[np.float64, ndim=1] + Observation vector. + + Returns + ------- + observation_f : ndarray[np.float64, ndim=1] + Filled observation vector. + """ + +def init_obs_covar_pdaf(step: int, dim_obs: int, dim_obs_p: int, + covar: np.ndarray, obs_p: np.ndarray, + isdiag: bool) -> Tuple[np.ndarray, bool]: + """Provide observation error covariance matrix to PDAF. + + This function is used in stochastic EnKF for generating observation perturbations. + + Parameters + ---------- + step: int + current time step + dim_obs : int + dimension of global observation vector + dim_obs_p: int + dimension of process-local observation vector + covar: np.ndarray[np.float64, dim=2] + Observation error covariance matrix. shape: (dim_obs_p, dim_obs_p) + obs_p: np.ndarray[np.float64, dim=1] + Process-local observation vector. shape: dim_obs_p + isdiag: bool + Flag indicating if the covariance matrix is diagonal. + + Returns + ------- + covar: np.ndarray[np.float64, dim=2] + Observation error covariance matrix. shape: (dim_obs_p, dim_obs_p) + is_diag: bool + Flag indicating if the covariance matrix is diagonal. + """ + +def init_obsvar_pdaf(step: int, dim_obs_p: int, obs_p: np.ndarray, meanvar: float) -> float: + """Compute mean observation error variance. + + This is used by ETKF-variants for adaptive forgetting factor (type_forget=1). + This can be global mean, or sub-domain mean. + + Parameters + ---------- + step: int + Current time step + dim_obs_p: int + Dimension of process-local observation vector + obs_p: np.ndarray[np.float64, dim=1] + Process-local observation vector. shape: (dim_obs_p,) + meanvar: float + Mean observation error variance. + + Returns + ------- + meanvar: float + Mean observation error variance. + """ + +def init_obsvars_pdaf(step: int, dim_obs_f: int, var_f: np.ndarray) -> np.ndarray: + """Provide a vector observation variance. + + This is used by EnSRF/EAKF. + + Parameters + ---------- + step: int + Current time step + dim_obs_f: int + Dimension of observation vector + var_f: np.ndarray[np.float64, dim=1] + Observation variance vector. shape: (dim_obs_f,) + + Returns + ------- + var_f: np.ndarray[np.float64, dim=1] + Observation variance vector. shape: (dim_obs_f,) + """ + +def prodrinva_pdaf(step: int, dim_obs_p: int, rank: int, + obs_p: np.ndarray, a_p: np.ndarray, c_p: np.ndarray) -> np.ndarray: + r"""Provide :math:`\mathbf{R}^{-1} \times \mathbf{A}`. + + Here, one should compute :math:`\mathbf{R}^{-1} \times \mathbf{A}` where + :math:`\mathbf{R}` is observation error covariance matrix. + The matrix :math:`\mathbf{A}` depends on the filter algorithm. In ESTKF, + :math:`\mathbf{R}` can is ensemble perturbation in observation space. + + Parameters + ---------- + step : int + Current time step + dim_obs_p : int + Dimension of observation vector + rank: int + Rank of the matrix A (second dimension of A) + This is ensemble size for ETKF and ensemble size - 1 for ESTKF. + obs_p: np.ndarray[np.float, dim=1] + Observation vector. shape: (dim_obs_p,) + a_p: np.ndarray[np.float, dim=2] + Input matrix A. shape: (dim_obs_p, rank) + c_p: np.ndarray[np.float, dim=2] + Output matrix :math:`\mathbf{C} = \mathbf{R}^{-1} \times \mathbf{A}`. + shape: (dim_obs_p, rank) + + Returns + ------- + c_p: np.ndarray[np.float64, dim=2] + Output matrix :math:`\mathbf{C} = \mathbf{R}^{-1} \times \mathbf{A}`. + shape: (dim_obs_p, rank) + """ + +def obs_op_pdaf(step: int, dim_p: int, dim_obs_p: int, + state_p: np.ndarray, m_state_p: np.ndarray) -> np.ndarray: + r"""Apply observation operator + + This function computes :math:`\mathbf{H} \mathbf{x}`, where + :math:`\mathbf{H}` is the observation operator and + :math:`\mathbf{x}` is state vector. + + Parameters + ---------- + step : int + Current step + dim_p : int + Dimension of state vector + dim_obs_p: int + Dimension of observation vector + state_p: np.ndarray[np.float, dim=1] + State vector. shape: (dim_p,) + m_state_p: np.ndarray[np.float, dim=1] + Observed state vector. shape: (dim_obs_p,) + + Returns + ------- + m_state_p: np.ndarray[np.float64, dim=1] + Observed state vector. shape: (dim_obs_p,) + """ + +def obs_op_f_pdaf(step: int, dim_p: int, dim_obs_p: int, + state_p: np.ndarray, m_state_p: np.ndarray) -> np.ndarray: + r"""Apply observation operator for full observed state vector + + This function computes :math:`\mathbf{H} \mathbf{x}`, where + :math:`\mathbf{H}` is the observation operator and + :math:`\mathbf{x}` is state vector. + See `here + `_ + for the meaning of full observations. + + Parameters + ---------- + step : int + Current step + dim_p : int + Dimension of state vector + dim_obs_p: int + Dimension of observation vector + state_p: np.ndarray[np.float, dim=1] + State vector. shape: (dim_p,) + m_state_p: np.ndarray[np.float, dim=1] + Observed state vector. shape: (dim_obs_p,) + + Returns + ------- + m_state_p: np.ndarray[np.float64, dim=1] + Observed state vector. shape: (dim_obs_p,) + """ + +def g2l_obs_pdaf(domain_p: int, step: int, dim_obs_f: int, + dim_obs_l: int, mstate_f: np.ndarray, mstate_l: np.ndarray) -> np.ndarray: + """Convert global observed state vector to local vector. + + This is used by domain localisation methods. In these methods, each local + domain has their own observation vector and observed state vector. + + Parameters + ---------- + domain_p:int + Current local domain index + step: int + Current time step + dim_obs_f: int + Global observation vector dimension. + dim_obs_l: int + Local observation vector dimension. + mstate_f: np.ndarray[np.float64, dim=1] + Global observed state vector. shape: (dim_obs_f,) + mstate_l: np.ndarray[np.float64, dim=1] + Local observed state vector. shape: (dim_obs_l,) + + Returns + ------- + mstate_l: np.ndarray[np.float64, dim=1] + Local observed state vector. shape: (dim_obs_l,) + """ + +def g2l_state_pdaf(step: int, domain_p: int, dim_p: int, + state_p: np.ndarray, dim_l: int, state_l: np.ndarray) -> np.ndarray: + """Get local state vector. + + Get the state vector for analysis local domain. + + Parameters + ---------- + step: int + Current time step + domain_p: int + Current local domain index + dim_p: int + Process-local state vector dimension. + state_p: np.ndarray[np.float, dim=1] + Process-local state vector. + dim_l: int + Local analysis domain state vector dimension. + state_l: np.ndarray[np.float, dim=1] + Local analysis domain state vector. Shape: (dim_l,) + + Returns + ------- + state_l: np.ndarray[np.float, dim=1] + Local analysis domain state vector. Shape: (dim_l,) + """ + +def init_dim_l_pdaf(step: int, domain_p: int, dim_l: int) -> int: + """Initialise local analysis domain state vector dimension. + + When PDAFlocal is used, one should call :func:`pyPDAF.PDAFlocal.set_indices` here. + + Parameters + ---------- + step: int + Current step + domain_p: int + Current local domain index + dim_l: int + Local analysis domain state vector dimension. + + Returns + ------- + dim_l: int + Local analysis domain state vector dimension. + """ + +def init_dim_obs_l_pdaf(domain_p: int, step: int, dim_obs_f: int, dim_obs_l: int) -> int: + """Initialise the dimension of local analysis domain observation vector. + + One can simplify this function by using :func:`pyPDAF.PDAFomi.init_dim_obs_l_xxx`. + + Parameters + ---------- + domain_p: int + Current local domain index + step: int + Current step + dim_obs_f: int + Global observation vector dimension. + dim_obs_l: int + Local observation vector dimension. + + Returns + ------- + dim_obs_l: int + Local observation vector dimension. + """ + +def init_n_domains_p_pdaf(step: int, n_domains_p: int) -> int: + """Get number of analysis domains. + + Parameters + ---------- + step: int + Current step + n_domains_p: int + Number of analysis domains. + + Returns + ------- + n_domains_p: int + Number of analysis domains. + """ + +def init_obs_l_pdaf(domain_p: int, step: int, dim_obs_l: int, + observation_l: np.ndarray) -> np.ndarray: + """Initialise observation vector for local analysis domain. + + Parameters + ---------- + domain_p: int + Current local domain index + step: int + Current time step + dim_obs_l: int + Local observation vector dimension. + observation_l: np.ndarray[np.float, dim=1] + Local observation vector. + + Returns + ------- + observation_l: np.ndarray[np.float, dim=1] + Local observation vector. + """ + +def init_obsvar_l_pdaf(domain_p: int, step: int, dim_obs_l: int, + obs_l: np.ndarray, dim_obs_p: int, meanvar_l: float) -> float: + """Get mean of analysis domain local observation variance. + + This is used by local adaptive forgetting factor (type_forget=2) + + Parameters + ---------- + domain_p: int + Current local domain index + step: int + Current time step + dim_obs_l: int + Local observation vector dimension. + obs_l: np.ndarray[np.float, dim=1] + Local observation vector. + dim_obs_p: int + Process-local observation vector dimension. + meanvar_l: float + Mean of analysis domain local observation variance. + + Returns + ------- + meanvar_l: float + Mean of analysis domain local observation variance. + """ + +def init_obserr_f_pdaf(step: int, dim_obs_f: int, + obs_f: np.ndarray, obserr_f: np.ndarray) -> np.ndarray: + """Initializes the full vector of observations error standard deviations. + + Parameters + ---------- + step : int + Current time step. + dim_obs_f : int + Full observation vector dimension. + obs_f : np.ndarray[np.float, dim=1] + Full observation vector. + obserr_f : np.ndarray[np.float, dim=1] + Full observation error vector. + + Returns + ------- + obserr_f : np.ndarray[np.float, dim=1] + Full observation error vector. + """ + +def l2g_state_pdaf(step: int, domain_p: int, dim_l: int, + state_l: np.ndarray, dim_p: int, state_p: np.ndarray) -> np.ndarray: + """Assign local state vector to process-local global state vector. + + Parameters + ---------- + step: int + Current time step + domain_p: int + Current local domain index + dim_l: int + Local analysis domain state vector dimension. + state_l: np.ndarray[np.float, dim=1] + Local analysis domain state vector. + dim_p: int + Process-local global state vector dimension. + state_p: np.ndarray[np.float, dim=1] + Process-local global state vector. + + Returns + ------- + state_p: np.ndarray[np.float, dim=1] + Process-local global state vector. + """ + +def prodrinva_l_pdaf(domain_p: int, step: int, dim_obs_l: int, + rank: int, obs_l: np.ndarray, a_l: np.ndarray, + c_l: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: + r"""Provide :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l`. + + Here, one should do :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l`. + The matrix :math:`\mathbf{A}_l` depends on the filter algorithm. + + One can also perform observation localisation. This can be helped by the function + :func:`pyPDAF.PDAF.local_weight` to get the observation weight. + + Parameters + ---------- + domain_p: int + Current local domain index. + step: int + Current time step + dim_obs_l: int + Dimension of observation vector in local analysis domain + rank: int + Rank of the local analysis domain + The size of it dpends on the filter algorithms. + obs_l: np.ndarray[np.float, dim=1] + Observation vector in local analysis domain. shape: (dim_obs_l, ) + a_l: np.ndarray[np.float, dim=2] + Matrix A in local analysis domain. + shape: (dim_obs_l, rank) + c_l: np.ndarray[np.float, dim=2] + :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l` in local analysis domain. + shape: (dim_obs_l, rank) + + Returns + ------- + c_l: np.ndarray[np.float, dim=2] + :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l` in local analysis domain. + shape: (dim_obs_l, rank) + """ + +def localize_covar_pdaf(dim_p: int, dim_obs: int, hp_p: np.ndarray, + hph: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: + """Perform covariance localisation. + + This is only used for stochastic EnKF. The localisation is performed + for HP and HPH.T. + + This can be helped by function :func:`pyPDAF.PDAFomi.localize_covar`. + This is replaced by :func:`PDAFomi.set_localize_covar` in PDAF3. + + Parameters + ---------- + dim_p: int + Dimension of the state vector. + dim_obs: int + Dimension of the observation vector. + hp_p: np.ndarray[np.float, dim=2] + Matrix HP. Shape: (dim_obs, dim_p) + hph: np.ndarray[np.float, dim=2] + Matrix HPH.T. Shape: (dim_obs, dim_obs) + + Returns + ------- + hp_p: np.ndarray[np.float, dim=2] + Localised matrix HP. Shape: (dim_obs, dim_p) + hph: np.ndarray[np.float, dim=2] + Localised matrix HPH.T. Shape: (dim_obs, dim_obs) + """ + +def localize_covar_serial_pdaf(iobs: int, dim_p: int, dim_obs:int, + hp_p: np.ndarray, hxy_p: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: + """Apply covariance localisation in EnSRF/EAKF. + + The localisation is applied to each observation element. The weight can be + obtained by :func:`pyPDAF.PDAF.local_weight`. + + Parameters + ---------- + iobs: int + Index of the observation element. + dim_p: int + Dimension of the state vector. + dim_obs: int + Dimension of the observation vector. + hp_p: np.ndarray[np.float, dim=1] + Matrix HP. Shape: (dim_p) + hxy_p: np.ndarray[np.float, dim=1] + Matrix HX (observed state). Shape: (dim_obs) + + Returns + ------- + hp_p: np.ndarray[np.float, dim=1] + Localised matrix HP. Shape: (dim_p) + hxy_p: np.ndarray[np.float, dim=1] + Localised matrix HX (observed state). Shape: (dim_obs) + """ + +def likelihood_pdaf(step: int, dim_obs_p: int, obs_p: np.ndarray, + resid: np.ndarray, likely: float) -> float: + r"""Compute the likelihood of the observation for a given ensemble member. + + The function is used with the nonlinear filter NETF and particle filter. The likelihood + depends on the assumed observation error distribution. + For a Gaussian observation error, the likelihood is + :math:`\exp(-0.5(\mathbf{y}-\mathbf{H}\mathbf{x})^\mathrm{T}R^{-1}(\mathbf{y}-\mathbf{H}\mathbf{x}))`. + The vector :math:`\mathbf{y}-\mathbf{H}\mathbf{x} = \mathrm{resid}` is + provided as an input argument. + + Parameters + ---------- + step: int + Current time step + dim_obs_p : int + Dimension of the observation vector. + obs_p: np.ndarray[np.float, dim=1] + Observation vector. Shape: (dim_obs_p) + resid: np.ndarray[np.float, dim=1] + Residual vector between observations and state. Shape: (dim_obs_p) + likely: float + Likelihood of the observation + + Returns + ------- + likely: float + Likelihood of the observation + """ + +def likelihood_l_pdaf(domain_p: int, step: int, dim_obs_l: int, + obs_l: np.ndarray, resid_l: np.ndarray, + double: float) -> float: + r"""Compute the likelihood of the observation for a given ensemble member + according to the observations used for the local analysis. + + The function is used in the localized nonlinear filter LNETF. The likelihood + depends on the assumed observation error distribution. + For a Gaussian observation error, the likelihood is + :math:`\exp(-0.5(\mathbf{y}-\mathbf{H}\mathbf{x})^\mathrm{T}R^{-1}(\mathbf{y}-\mathbf{H}\mathbf{x}))`. + The vector :math:`\mathbf{y}-\mathbf{H}\mathbf{x} = \mathrm{resid}` is + provided as an input argument. + + This function is also the place to perform observation localisation. + To initialize a vector of weights, the routine :func:`pyPDAF.PDAF.local_weight` + can be called. + + Parameters + ---------- + domain_p: int + Current local analysis domain index + step: int + Current time step + dim_obs_l: int + Dimension of the local observation vector. + obs_l: np.ndarray[np.float, dim=1] + Observation vector. Shape: (dim_obs_l) + resid_l: np.ndarray[np.float, dim=1] + Residual vector between observations and state. Shape: (dim_obs_l) + likely_l: float + Likelihood of the local observation + + Returns + ------- + likely_l: float + Likelihood of the local observation + """ + +def get_obs_f_pdaf(step: int, dim_obs_f: int, observation_f: np.ndarray) -> np.ndarray: + """Receive synthetic observations from PDAF. + + This function is used in twin experiments for observation generations. + One can, for example, save synthetic observations in this function. + + Parameters + ---------- + step: int + Current time step + dim_obs_f: int + Full observation vector dimension. + observation_f: np.ndarray[np.float, dim=1] + Full observation vector. + + Returns + ------- + observation_f: np.ndarray[np.float, dim=1] + Full observation vector. + """ + +def cvt_adj_ens_pdaf(iter: int, dim_p: int, dim_ens: int, dim_cv_ens_p:int, + ens: np.ndarray, vcv_p: np.ndarray, cv_p: np.ndarray) -> np.ndarray: + r"""The adjoint control variable transformation involving ensembles. + + Here, this function performs + :math:`\mathbf{U}^\mathrm{T} \mathbf{v}_h`. Here, the input vector can be + :math:`\mathbf{v}_h = \mathbf{H}^\mathrm{T}\mathbf{R}^{-1}\delta \mathbf{x}` + with :math:`\delta \mathbf{x}` the innovation vector. + + The control vector transform is given by :math:`\mathbf{U}\mathbf{v}` with + :math:`\mathbf{v}` the control vector and :math:`\mathbf{U}` the transformation + matrix, which can be :math:`\mathbf{B}^\frac{1}{2}`. + + This function is used in 3DEnVar and hybrid 3DVar. + + Parameters + ---------- + iter: int + Current optimisation iteration number. + dim_p: int + Dimension of the state vector. + dim_ens: int + Dimension of the ensemble. + dim_cv_ens_p: int + Dimension of the control vector. + ens_p: np.ndarray[np.float, dim=2] + Ensemble matrix. shape: (dim_p, dim_ens) + vcv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{v}_h`. shape: (dim_p, ) + cv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U}^\mathrm{T} \mathbf{v}_h`. shape: (dim_cv_ens_p, ) + + Returns + ------- + cv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U}^\mathrm{T} \mathbf{v}_h`. shape: (dim_cv_ens_p, ) + """ + +def cvt_adj_pdaf(iter: int, dim_p: int, dim_cvec: int, + vcv_p: np.ndarray, cv_p: np.ndarray) -> np.ndarray: + r"""The adjoint control variable transformation. + + Here, this function performs + :math:`\mathbf{U}^\mathrm{T} \mathbf{v}_h`. Here, the input vector can be + :math:`\mathbf{v}_h = \mathbf{H}^\mathrm{T}\mathbf{R}^{-1}\delta \mathbf{x}` + with :math:`\delta \mathbf{x}` the innovation vector. + + The control vector transform is given by :math:`\mathbf{U}\mathbf{v}` with + :math:`\mathbf{v}` the control vector and :math:`\mathbf{U}` the transformation + matrix, which can be :math:`\mathbf{B}^\frac{1}{2}`. + + This function is used in 3DVar and hybrid 3DVar. + + Parameters + ---------- + iter: int + Current optimisation iteration number. + dim_p: int + Dimension of the state vector. + dim_cvec: int + Dimension of the control vector. + vcv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{v}_h`. shape: (dim_p, ) + cv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U}^\mathrm{T} \mathbf{v}_h`. shape: (dim_cvec, ) + + Returns + ------- + cv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U}^\mathrm{T} \mathbf{v}_h`. shape: (dim_cvec, ) + """ + +def cvt_pdaf(iter: int, dim_p: int, dim_cvec: int, + cv_p: np.ndarray, vv_p: np.ndarray) -> np.ndarray: + r"""The control variable transformation. + + Here, this function performs :math:`\mathbf{U} \mathbf{v}` with + :math:`\mathbf{v}` the control vector and :math:`\mathbf{U}` the transformation + matrix, which can be :math:`\mathbf{B}^\frac{1}{2}`. + + This function is used in 3DVar and hybrid 3DVar. + + Parameters + ---------- + iter: int + Current optimisation iteration number. + dim_p: int + Dimension of the state vector. + dim_cvec: int + Dimension of the control vector. + cv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{v}`. shape: (dim_cvec, ) + vv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U} \mathbf{v}`. shape: (dim_p, ) + + Returns + ------- + vv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U} \mathbf{v}`. shape: (dim_p, ) + """ + +def cvt_ens_pdaf(iter: int, dim_p: int, dim_ens: int, dim_cv_ens_p: int, + v_p: np.ndarray, vv_p: np.ndarray) -> np.ndarray: + r"""The control variable transformation involving ensembles. + + Here, this function performs :math:`\mathbf{U} \mathbf{v}` with + :math:`\mathbf{v}` the control vector and :math:`\mathbf{U}` the transformation + matrix, which can be :math:`\mathbf{B}^\frac{1}{2}`. + + This function is used in 3DEnVar and hybrid 3DVar. + + Parameters + ---------- + iter: int + Current optimisation iteration number. + dim_p: int + Dimension of the state vector. + dim_ens: int + Dimension of the ensemble. + dim_cv_ens_p: int + Dimension of the control vector. + ens_p: np.ndarray[np.float, dim=2] + Ensemble matrix. shape: (dim_p, dim_ens) + v_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{v}`. shape: (dim_cv_ens_p, ) + vv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U} \mathbf{v}`. shape: (dim_p, ) + + Returns + ------- + vv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U} \mathbf{v}`. shape: (dim_p, ) + """ + +def obs_op_adj_pdaf(step: int, dim_p: int, dim_obs_p: int, + m_state_p: np.ndarray, state_p: np.ndarray) -> np.ndarray: + r"""Apply adjoint observation operator + + This function computes :math:`\mathbf{H}^\mathrm{T} \mathbf{w}`, where + :math:`\mathbf{H}` is the observation operator and + :math:`\mathbf{w}` is a vector in observation space. + + Parameters + ---------- + step : int + Current step + dim_p : int + Dimension of state vector + dim_obs_p: int + Dimension of observation vector + m_state_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{w}`. shape: (dim_obs_p,) + state_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{H}^\mathrm{T} \mathbf{w}`. shape: (dim_p,) + + Returns + ------- + state_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{H}^\mathrm{T} \mathbf{w}`. shape: (dim_p,) + """ + +def obs_op_lin_pdaf(step: int, dim_p: int, dim_obs_p: int, + state_p: np.ndarray, m_state_p: np.ndarray) -> np.ndarray: + r"""Apply linearised observation operator + + This function computes :math:`\mathbf{H} \mathbf{x}`, where + :math:`\mathbf{H}` is the linearised observation operator and + :math:`\mathbf{x}` is state vector. + + Parameters + ---------- + step : int + Current step + dim_p : int + Dimension of state vector + dim_obs_p: int + Dimension of observation vector + state_p: np.ndarray[np.float, dim=1] + State vector. shape: (dim_p,) + m_state_p: np.ndarray[np.float, dim=1] + Observed state vector. shape: (dim_obs_p,) + + Returns + ------- + m_state_p: np.ndarray[np.float64, dim=1] + Observed state vector. shape: (dim_obs_p,) + """ + +def likelihood_hyb_l_pdaf(domain_p: int, step: int, dim_obs_l: int, + obs_l: np.ndarray, gamma: float, resid_l: np.ndarray, + likely_l: np.ndarray) -> float: + r"""Compute the likelihood of the observation for a given ensemble member + according to the observations used for the local analysis with hybrid weight. + + The function is used in the localized nonlinear filter LKNETF. The likelihood + depends on the assumed observation error distribution. + For a Gaussian observation error, the likelihood is + :math:`\exp(-0.5(\mathbf{y}-\mathbf{H}\mathbf{x})^\mathrm{T}R^{-1}(\mathbf{y}-\mathbf{H}\mathbf{x}))`. + The vector :math:`\mathbf{y}-\mathbf{H}\mathbf{x} = \mathrm{resid}` is + provided as an input argument. + + The hybrid weight `gamma` is used weight between LNETF and LETKF. which is applied + to :math:`R^{-1}(\mathbf{y}-\mathbf{H}\mathbf{x})`. + + This function is also the place to perform observation localisation. + To initialize a vector of weights, the routine :func:`pyPDAF.PDAF.local_weight` + can be called. + + Parameters + ---------- + domain_p: int + Current local analysis domain index + step: int + Current time step + dim_obs_l: int + Dimension of the local observation vector. + obs_l: np.ndarray[np.float, dim=1] + Observation vector. Shape: (dim_obs_l) + gamma: float + Hybrid weight provided by PDAF + resid_l: np.ndarray[np.float, dim=1] + Residual vector between observations and state. Shape: (dim_obs_l) + likely_l: float + Likelihood of the local observation + + Returns + ------- + likely_l: float + Likelihood of the local observation + + """ + +def prodrinva_hyb_l_pdaf(domain_p: int, step: int, dim_obs_l: int, rank: int, + obs_l: np.ndarray, gamma: float, + a_l: np.ndarray, c_l: np.ndarray) -> np.ndarray: + r"""Provide :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l` with weighting. + + Here, one should do :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l`. + The matrix :math:`\mathbf{A}_l` depends on the filter algorithm. + + This function is used in LKNETF where `gamma` is multipled with `c_l` for + weighting between LETKF and LNETF. + + One can also perform observation localisation. This can be helped by the function + :func:`pyPDAF.PDAF.local_weight` to get the observation weight. + + Parameters + ---------- + domain_p: int + Current local domain index. + step: int + Current time step + dim_obs_l: int + Dimension of observation vector in local analysis domain + rank: int + Rank of the local analysis domain + The size of it dpends on the filter algorithms. + obs_l: np.ndarray[np.float, dim=1] + Observation vector in local analysis domain. shape: (dim_obs_l, ) + gamma: float + Hybrid weight provided by PDAF + a_l: np.ndarray[np.float, dim=2] + Matrix A in local analysis domain. shape: (dim_obs_l, rank) + c_l: np.ndarray[np.float, dim=2] + :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l` in local analysis domain. + shape: (dim_obs_l, rank) + + Returns + ------- + c_l: np.ndarray[np.float, dim=2] + :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l` in local analysis domain. + shape: (dim_obs_l, rank) + """ diff --git a/pyPDAF/source/src/pyPDAF/pdaf_c_cb_interface.pyx b/pyPDAF/source/src/pyPDAF/pdaf_c_cb_interface.pyx new file mode 100644 index 0000000000000000000000000000000000000000..2bb51cd7f13f71c1532bebb5508b2d00eb81fe3b --- /dev/null +++ b/pyPDAF/source/src/pyPDAF/pdaf_c_cb_interface.pyx @@ -0,0 +1,1676 @@ +import sys +import numpy as np +import warnings + +cdef void c__add_obs_err_pdaf(int* step, int* dim_obs_p, + double* c_p) noexcept with gil: + """Add the observation error covariance matrix to the matrix C. + + The input matrix is the projection of the ensemble + covariance matrix onto the observation space that is computed + during the analysis step of the stochastic EnKF. That is, HPH.T. + The function returns HPH.T + R. + + The operation is for the global observation space. + Thus, it is independent of whether the filter is executed with or + without parallelization. + + Parameters + ---------- + step : int + Current time step + dim_obs_p : int + Size of observation vector + C_p : ndarray[np.float64, ndim=2] + Matrix to which the observation error covariance matrix is added + shape: (dim_obs_p, dim_obs_p) + + Returns + ------- + C_p : ndarray[np.float64, ndim=2] + Matrix with added obs error covariance, i.e., HPH.T + R + shape: (dim_obs_p, dim_obs_p) + """ + cdef double[::1,:] c_p_np = np.asarray( c_p, order="F") + + c_p_np = (add_obs_err_pdaf)(step[0], dim_obs_p[0], c_p_np.base) + + cdef double[::1,:] c_p_new + if c_p != &c_p_np[0,0]: + c_p_new = np.asarray( c_p, order="F") + c_p_new[...] = c_p_np + warnings.warn("The memory address of c_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__init_ens_pdaf(int* filtertype, int* dim_p, int* dim_ens, + double* state_p, double* uinv, double* ens_p, int* flag) noexcept with gil: + """Fill the ensemble array that is provided by PDAF with an initial ensemble of model states. + + This function is called by :func:`pyPDAF.PDAF.init`. The initialised + ensemble array will be distributed to model by :func:`pyPDAF.PDAF.init_forecast`. + + Parameters + ---------- + filtertype : int + filter type given in PDAF_init + dim_p : int + PE-local state dimension given by PDAF_init + dim_ens : int + number of ensemble members + state_p : ndarray[np.float64, ndim=1] + PE-local model state + This array must be filled with the initial + state of the model for SEEK, but it is not + used for ensemble-based filters. + One can still make use of this array within + this function. + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + This array is the inverse of matrix + formed by right singular vectors of error + covariance matrix of ensemble perturbations. + This array has to be filled in SEEK, but it is + not used for ensemble-based filters. + Nevertheless, one can still make use of this + array within this function e.g., + for generating an initial ensemble perturbation + from a given covariance matrix. + Dimension of this array is determined by the + filter type. + * (dim_ens, dim_ens) for (L)ETKF, (L)NETF, (L)KNETF, and SEEK + * (dim_ens - 1, dim_ens - 1) for (L)SEIK, (L)ESTKF, and 3DVar using ensemble + * (1, 1) for (L)EnKF, particle filters and gen_obs + Array shape: (dim_ens - 1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + PE-local model state + This array must be filled with the initial + state of the model for SEEK, but it is not + used for ensemble-based filters. + One can still make use of this array within + this function. + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + This array is the inverse of matrix + formed by right singular vectors of error + covariance matrix of ensemble perturbations. + This array has to be filled in SEEK, but it is + not used for ensemble-based filters. + Nevertheless, one can still make use of this + array within this function e.g., + for generating an initial ensemble perturbation + from a given covariance matrix. + Dimension of this array is determined by the + filter type. + * (dim_ens, dim_ens) for (L)ETKF, (L)NETF, (L)KNETF, and SEEK + * (dim_ens - 1, dim_ens - 1) for (L)SEIK, (L)ESTKF, and 3DVar using ensemble + * (1, 1) for (L)EnKF, particle filters and gen_obs + Array shape: (dim_ens - 1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + """ + cdef size_t uinv_len = max(dim_ens[0]-1, 1) + cdef double[::1] state_p_np = np.asarray( state_p, order="F") + cdef double[::1,:] uinv_np = np.asarray( uinv, order="F") + cdef double[::1,:] ens_p_np = np.asarray( ens_p, order="F") + + state_p_np,uinv_np,ens_p_np,flag[0] = (init_ens_pdaf)( + filtertype[0], + dim_p[0], + dim_ens[0], + state_p_np.base, + uinv_np.base, + ens_p_np.base, + flag[0]) + + cdef double[::1] state_p_new + if state_p != &state_p_np[0]: + state_p_new = np.asarray( state_p, order="F") + state_p_new[...] = state_p_np + warnings.warn("The memory address of state_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + cdef double[::1,:] uinv_new + if uinv != &uinv_np[0,0]: + uinv_new = np.asarray( uinv, order="F") + uinv_new[...] = uinv_np + warnings.warn("The memory address of uinv is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + cdef double[::1,:] ens_p_new + if ens_p != &ens_p_np[0,0]: + ens_p_new = np.asarray( ens_p, order="F") + ens_p_new[...] = ens_p_np + warnings.warn("The memory address of ens_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__next_observation_pdaf(int* stepnow, int* nsteps, int* doexit, + double* time) noexcept with gil: + """Get the number of time steps to be computed in the forecast phase. + + At the beginning of a forecast phase, this is called once by + * :func:`pyPDAF.PDAF.init_forecast` + * :func:`pyPDAF.PDAF3.assimilate_X` + * ... + + Parameters + ---------- + stepnow : int + the current time step given by PDAF + + Returns + ------- + nsteps : int + number of forecast time steps until next assimilation; + this can also be interpreted as + number of assimilation function calls + to perform a new assimilation + doexit : int + whether to exit forecasting (1 for exit) + time : double + current model (physical) time + """ + nsteps[0],doexit[0],time[0] = (next_observation_pdaf)( + stepnow[0], + nsteps[0], + doexit[0], + time[0]) + + + +cdef void c__collect_state_pdaf(int* dim_p, double* state_p) noexcept with gil: + """Collect state vector from model/any arrays to pdaf arrays + + Parameters + ---------- + dim_p : int + pe-local state dimension + + state_p : ndarray[tuple[dim_p, ...], np.float64] + local state vector + + Returns + ------- + state_p : ndarray[tuple[dim_p, ...], np.float64] + local state vector + """ + cdef double[::1] state_p_np = np.asarray( state_p, order="F") + + state_p_np = (collect_state_pdaf)(dim_p[0], state_p_np.base) + + cdef double[::1] state_p_new + if state_p != &state_p_np[0]: + state_p_new = np.asarray( state_p, order="F") + state_p_new[...] = state_p_np + warnings.warn("The memory address of state_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__distribute_state_pdaf(int* dim_p, + double* state_p) noexcept with gil: + """Distribute a state vector from pdaf to the model/any arrays + + Parameters + ---------- + dim_p : int + PE-local state dimension + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + PE-local state vector + Array shape: (dim_p) + """ + cdef double[::1] state_p_np = np.asarray( state_p, order="F") + + state_p_np = (distribute_state_pdaf)(dim_p[0], state_p_np.base) + + cdef double[::1] state_p_new + if state_p != &state_p_np[0]: + state_p_new = np.asarray( state_p, order="F") + state_p_new[...] = state_p_np + warnings.warn("The memory address of state_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__prepoststep_pdaf(int* step, int* dim_p, int* dim_ens, + int* dim_ens_l, int* dim_obs_p, double* state_p, double* uinv, + double* ens_p, int* flag) noexcept with gil: + """Process ensemble before or after DA. + + Parameters + ---------- + step : int + current time step + (negative for call before analysis/preprocessing) + dim_p : int + PE-local state vector dimension + dim_ens : int + number of ensemble members + dim_ens_l : int + number of ensemble members run serially + on each model task + dim_obs_p : int + PE-local dimension of observation vector + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + flag : int + pdaf status flag + + Returns + ------- + state_p : ndarray[np.float64, ndim=1] + pe-local forecast/analysis state + (the array 'state_p' is generally not + initialised in the case of ESTKF/ETKF/EnKF/SEIK, + so it can be used freely here.) + Array shape: (dim_p) + uinv : ndarray[np.float64, ndim=2] + Inverse of the transformation matrix in ETKF and ESKTF; + inverse of matrix formed by right singular vectors of error + covariance matrix of ensemble perturbations in SEIK/SEEK. + not used in EnKF. + Array shape: (dim_ens-1, dim_ens-1) + ens_p : ndarray[np.float64, ndim=2] + PE-local ensemble + Array shape: (dim_p, dim_ens) + """ + cdef size_t uinv_len = max(dim_ens[0]-1, 1) + cdef double[::1] state_p_np = np.asarray( state_p, order="F") + cdef double[::1,:] uinv_np = np.asarray( uinv, order="F") + cdef double[::1,:] ens_p_np = np.asarray( ens_p, order="F") + + state_p_np,uinv_np,ens_p_np = (prepoststep_pdaf)(step[0], + dim_p[0], + dim_ens[0], + dim_ens_l[0], + dim_obs_p[0], + state_p_np.base, + uinv_np.base, + ens_p_np.base, + flag[0]) + + cdef double[::1] state_p_new + if state_p != &state_p_np[0]: + state_p_new = np.asarray( state_p, order="F") + state_p_new[...] = state_p_np + warnings.warn("The memory address of state_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + cdef double[::1,:] uinv_new + if uinv != &uinv_np[0,0]: + uinv_new = np.asarray( uinv, order="F") + uinv_new[...] = uinv_np + warnings.warn("The memory address of uinv is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + cdef double[::1,:] ens_p_new + if ens_p != &ens_p_np[0,0]: + ens_p_new = np.asarray( ens_p, order="F") + ens_p_new[...] = ens_p_np + warnings.warn("The memory address of ens_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__init_dim_obs_pdaf(int* step, int* dim_obs_p) noexcept with gil: + """Determine the size of the vector of observations + + The primary purpose of this function is to + obtain the dimension of the observation vector. + In OMI, in this function, one also sets the properties + of `obs_f`, read the observation vector from + files, setting the observation error variance + when diagonal observation error covariance matrix + is used. The `pyPDAF.PDAF.omi_gather_obs` function + is also called here. + + Furthermore, in this user-supplied function, one also sets the interpolation + coefficients used by observation operators. + + Parameters + ---------- + step : int + Current time step. + dim_obs_p : int + Dimension of the observation vector. + + Returns + ------- + dim_obs_p : int + Dimension of the observation vector. + """ + dim_obs_p[0] = (init_dim_obs_pdaf)(step[0], dim_obs_p[0]) + + + +cdef void c__init_dim_obs_f_pdaf(int* step, int* dim_obs_f) noexcept with gil: + """Determine the size of the full observations vector + + This function is used with domain localised filters to obtain the dimension of full + observation vector that contains observations outside process-local domains. + The smallest vector only needs observations within localisation radius of the + process-local domain. + + Parameters + ---------- + step : int + Current time step. + dim_obs_f : int + Dimension of the full observation vector. + + Returns + ------- + dim_obs_f : int + Dimension of the full observation vector. + """ + dim_obs_f[0] = (init_dim_obs_f_pdaf)(step[0], dim_obs_f[0]) + + + +cdef void c__init_obs_pdaf(int* step, int* dim_obs_p, + double* observation_p) noexcept with gil: + """Provide the observation vector for the current time step. + + Parameters + ---------- + step : int + Current time step. + dim_obs_p : int + Dimension of the observation vector. + observation_p : ndarray[np.float64, ndim=1] + Observation vector. + + Returns + ------- + observation_p : ndarray[np.float64, ndim=1] + Filled observation vector. + """ + cdef double[::1] observation_p_np = np.asarray( observation_p, order="F") + + observation_p_np = (init_obs_pdaf)(step[0], dim_obs_p[0], + observation_p_np.base) + + cdef double[::1] observation_p_new + if observation_p != &observation_p_np[0]: + observation_p_new = np.asarray( observation_p, order="F") + observation_p_new[...] = observation_p_np + warnings.warn("The memory address of observation_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + +cdef void c__init_obs_f_pdaf(int* step, int* dim_obs_f, + double* observation_f) noexcept with gil: + """Provide the observation vector for the current time step. + + This function is used with domain localised filters to obtain a full + observation vector that contains observations outside process-local domains. + The smallest vector only needs observations within localisation radius of the + process-local domain. + + Parameters + ---------- + step : int + Current time step. + dim_obs_f : int + Dimension of the observation vector. + observation_f : ndarray[np.float64, ndim=1] + Observation vector. + + Returns + ------- + observation_f : ndarray[np.float64, ndim=1] + Filled observation vector. + """ + cdef double[::1] observation_f_np = np.asarray( observation_f, order="F") + + observation_f_np = (init_obs_f_pdaf)(step[0], dim_obs_f[0], + observation_f_np.base) + + cdef double[::1] observation_f_new + if observation_f != &observation_f_np[0]: + observation_f_new = np.asarray( observation_f, order="F") + observation_f_new[...] = observation_f_np + warnings.warn("The memory address of observation_f is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + + +cdef void c__init_obs_covar_pdaf(int* step, int* dim_obs, int* dim_obs_p, + double* covar, double* obs_p, bint* isdiag) noexcept with gil: + """Provide observation error covariance matrix to PDAF. + + This function is used in stochastic EnKF for generating observation perturbations. + + Parameters + ---------- + step: int + current time step + dim_obs : int + dimension of global observation vector + dim_obs_p: int + dimension of process-local observation vector + covar: np.ndarray[np.float64, dim=2] + Observation error covariance matrix. shape: (dim_obs_p, dim_obs_p) + obs_p: np.ndarray[np.float64, dim=1] + Process-local observation vector. shape: dim_obs_p + isdiag: bool + Flag indicating if the covariance matrix is diagonal. + + Returns + ------- + covar: np.ndarray[np.float64, dim=2] + Observation error covariance matrix. shape: (dim_obs_p, dim_obs_p) + is_diag: bool + Flag indicating if the covariance matrix is diagonal. + """ + cdef double[::1,:] covar_np = np.asarray( covar, order="F") + cdef double[::1] obs_p_np = np.asarray( obs_p, order="F") + + covar_np,isdiag[0] = (init_obs_covar_pdaf)(step[0], dim_obs[0], + dim_obs_p[0], + covar_np.base, + obs_p_np.base, isdiag[0]) + + cdef double[::1,:] covar_new + if covar != &covar_np[0,0]: + covar_new = np.asarray( covar, order="F") + covar_new[...] = covar_np + warnings.warn("The memory address of covar is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__init_obsvar_pdaf(int* step, int* dim_obs_p, double* obs_p, + double* meanvar) noexcept with gil: + """Compute mean observation error variance. + + This is used by ETKF-variants for adaptive forgetting factor (type_forget=1). + This can be global mean, or sub-domain mean. + + Parameters + ---------- + step: int + Current time step + dim_obs_p: int + Dimension of process-local observation vector + obs_p: np.ndarray[np.float64, dim=1] + Process-local observation vector. shape: (dim_obs_p,) + meanvar: float + Mean observation error variance. + + Returns + ------- + meanvar: float + Mean observation error variance. + """ + cdef double[::1] obs_p_np = np.asarray( obs_p, order="F") + + meanvar[0] = (init_obsvar_pdaf)(step[0], dim_obs_p[0], + obs_p_np.base, meanvar[0]) + + + +cdef void c__init_obsvars_pdaf(int* step, int* dim_obs_f, + double* var_f) noexcept with gil: + """Provide a vector observation variance. + + This is used by EnSRF/EAKF. + + Parameters + ---------- + step: int + Current time step + dim_obs_f: int + Dimension of observation vector + var_f: np.ndarray[np.float64, dim=1] + Observation variance vector. shape: (dim_obs_f,) + + Returns + ------- + var_f: np.ndarray[np.float64, dim=1] + Observation variance vector. shape: (dim_obs_f,) + """ + cdef double[::1] var_f_np = np.asarray( var_f, order="F") + + var_f_np = (init_obsvars_pdaf)(step[0], dim_obs_f[0], var_f_np.base) + + cdef double[::1] var_f_new + if var_f != &var_f_np[0]: + var_f_new = np.asarray( var_f, order="F") + var_f_new[...] = var_f_np + warnings.warn("The memory address of var_f is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__prodrinva_pdaf(int* step, int* dim_obs_p, int* rank, + double* obs_p, double* a_p, double* c_p) noexcept with gil: + """Provide :math:`\mathbf{R}^{-1} \\times \mathbf{A}`. + + Here, one should compute :math:`\mathbf{R}^{-1} \times \mathbf{A}` where + :math:`\mathbf{R}` is observation error covariance matrix. + The matrix :math:`\mathbf{A}` depends on the filter algorithm. In ESTKF, + :math:`\mathbf{R}` can is ensemble perturbation in observation space. + + Parameters + ---------- + step : int + Current time step + dim_obs_p : int + Dimension of observation vector + rank: int + Rank of the matrix A (second dimension of A) + This is ensemble size for ETKF and ensemble size - 1 for ESTKF. + obs_p: np.ndarray[np.float, dim=1] + Observation vector. shape: (dim_obs_p,) + a_p: np.ndarray[np.float, dim=2] + Input matrix A. shape: (dim_obs_p, rank) + c_p: np.ndarray[np.float, dim=2] + Output matrix :math:`\mathbf{C} = \mathbf{R}^{-1} \times \mathbf{A}`. + shape: (dim_obs_p, rank) + + Returns + ------- + c_p: np.ndarray[np.float64, dim=2] + Output matrix :math:`\mathbf{C} = \mathbf{R}^{-1} \times \mathbf{A}`. + shape: (dim_obs_p, rank) + """ + cdef double[::1] obs_p_np = np.asarray( obs_p, order="F") + cdef double[::1,:] a_p_np = np.asarray( a_p, order="F") + cdef double[::1,:] c_p_np = np.asarray( c_p, order="F") + + c_p_np = (prodrinva_pdaf)(step[0], dim_obs_p[0], rank[0], + obs_p_np.base, a_p_np.base, c_p_np.base) + + cdef double[::1,:] c_p_new + if c_p != &c_p_np[0,0]: + c_p_new = np.asarray( c_p, order="F") + c_p_new[...] = c_p_np + warnings.warn("The memory address of c_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__obs_op_pdaf(int* step, int* dim_p, int* dim_obs_p, + double* state_p, double* m_state_p) noexcept with gil: + """Apply observation operator + + This function computes :math:`\mathbf{H} \mathbf{x}`, where + :math:`\mathbf{H}` is the observation operator and + :math:`\mathbf{x}` is state vector. + + Parameters + ---------- + step : int + Current step + dim_p : int + Dimension of state vector + dim_obs_p: int + Dimension of observation vector + state_p: np.ndarray[np.float, dim=1] + State vector. shape: (dim_p,) + m_state_p: np.ndarray[np.float, dim=1] + Observed state vector. shape: (dim_obs_p,) + + Returns + ------- + m_state_p: np.ndarray[np.float64, dim=1] + Observed state vector. shape: (dim_obs_p,) + """ + cdef double[::1] state_p_np = np.asarray( state_p, order="F") + cdef double[::1] m_state_p_np = np.asarray( m_state_p, order="F") + + m_state_p_np = (obs_op_pdaf)(step[0], dim_p[0], dim_obs_p[0], + state_p_np.base, m_state_p_np.base) + + cdef double[::1] m_state_p_new + if m_state_p != &m_state_p_np[0]: + m_state_p_new = np.asarray( m_state_p, order="F") + m_state_p_new[...] = m_state_p_np + warnings.warn("The memory address of m_state_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__obs_op_f_pdaf(int* step, int* dim_p, int* dim_obs_p, + double* state_p, double* m_state_p) noexcept with gil: + """Apply observation operator for full observed state vector + + This function computes :math:`\mathbf{H} \mathbf{x}`, where + :math:`\mathbf{H}` is the observation operator and + :math:`\mathbf{x}` is state vector. + See `here `_ + for the meaning of full observations. + + Parameters + ---------- + step : int + Current step + dim_p : int + Dimension of state vector + dim_obs_p: int + Dimension of observation vector + state_p: np.ndarray[np.float, dim=1] + State vector. shape: (dim_p,) + m_state_p: np.ndarray[np.float, dim=1] + Observed state vector. shape: (dim_obs_p,) + + Returns + ------- + m_state_p: np.ndarray[np.float64, dim=1] + Observed state vector. shape: (dim_obs_p,) + """ + cdef double[::1] state_p_np = np.asarray( state_p, order="F") + cdef double[::1] m_state_p_np = np.asarray( m_state_p, order="F") + + m_state_p_np = (obs_op_f_pdaf)(step[0], dim_p[0], dim_obs_p[0], + state_p_np.base, m_state_p_np.base) + + cdef double[::1] m_state_p_new + if m_state_p != &m_state_p_np[0]: + m_state_p_new = np.asarray( m_state_p, order="F") + m_state_p_new[...] = m_state_p_np + warnings.warn("The memory address of m_state_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__g2l_obs_pdaf(int* domain_p, int* step, int* dim_obs_f, + int* dim_obs_l, int* mstate_f, int* mstate_l) noexcept with gil: + """Convert global observed state vector to local vector. + + This is used by domain localisation methods. In these methods, each local + domain has their own observation vector and observed state vector. + + Parameters + ---------- + domain_p:int + Current local domain index + step: int + Current time step + dim_obs_f: int + Global observation vector dimension. + dim_obs_l: int + Local observation vector dimension. + mstate_f: np.ndarray[np.float64, dim=1] + Global observed state vector. shape: (dim_obs_f,) + mstate_l: np.ndarray[np.float64, dim=1] + Local observed state vector. shape: (dim_obs_l,) + + Returns + ------- + mstate_l: np.ndarray[np.float64, dim=1] + Local observed state vector. shape: (dim_obs_l,) + """ + cdef int[::1] mstate_f_np = np.asarray( mstate_f, order="F") + cdef int[::1] mstate_l_np = np.asarray( mstate_l, order="F") + + mstate_l_np = (g2l_obs_pdaf)(domain_p[0], step[0], + dim_obs_f[0], dim_obs_l[0], + mstate_f_np.base, mstate_l_np.base) + + cdef int[::1] mstate_l_new + if mstate_l != &mstate_l_np[0]: + mstate_l_new = np.asarray( mstate_l, order="F") + mstate_l_new[...] = mstate_l_np + warnings.warn("The memory address of mstate_l is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__g2l_state_pdaf(int* step, int* domain_p, int* dim_p, + double* state_p, int* dim_l, double* state_l) noexcept with gil: + """Get local state vector. + + Get the state vector for analysis local domain. + + Parameters + ---------- + step: int + Current time step + domain_p: int + Current local domain index + dim_p: int + Process-local state vector dimension. + state_p: np.ndarray[np.float, dim=1] + Process-local state vector. + dim_l: int + Local analysis domain state vector dimension. + state_l: np.ndarray[np.float, dim=1] + Local analysis domain state vector. Shape: (dim_l,) + + Returns + ------- + state_l: np.ndarray[np.float, dim=1] + Local analysis domain state vector. Shape: (dim_l,) + """ + cdef double[::1] state_p_np = np.asarray( state_p, order="F") + cdef double[::1] state_l_np = np.asarray( state_l, order="F") + + state_l_np = (g2l_state_pdaf)(step[0], domain_p[0], dim_p[0], + state_p_np.base, dim_l[0], + state_l_np.base) + + cdef double[::1] state_l_new + if state_l != &state_l_np[0]: + state_l_new = np.asarray( state_l, order="F") + state_l_new[...] = state_l_np + warnings.warn("The memory address of state_l is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__init_dim_l_pdaf(int* step, int* domain_p, + int* dim_l) noexcept with gil: + """Initialise local analysis domain state vector dimension. + + When PDAFlocal is used, one should call :func:`pyPDAF.PDAFlocal.set_indices` here. + + Parameters + ---------- + step: int + Current step + domain_p: int + Current local domain index + dim_l: int + Local analysis domain state vector dimension. + + Returns + ------- + dim_l: int + Local analysis domain state vector dimension. + """ + + dim_l[0] = (init_dim_l_pdaf)(step[0], domain_p[0], dim_l[0]) + + + +cdef void c__init_dim_obs_l_pdaf(int* domain_p, int* step, int* dim_obs_f, + int* dim_obs_l) noexcept with gil: + """Initialise the dimension of local analysis domain observation vector. + + One can simplify this function by using :func:`pyPDAF.PDAFomi.init_dim_obs_l_xxx`. + + Parameters + ---------- + domain_p: int + Current local domain index + step: int + Current step + dim_obs_f: int + Global observation vector dimension. + dim_obs_l: int + Local observation vector dimension. + + Returns + ------- + dim_obs_l: int + Local observation vector dimension. + """ + dim_obs_l[0] = (init_dim_obs_l_pdaf)(domain_p[0], step[0], + dim_obs_f[0], dim_obs_l[0]) + + + +cdef void c__init_n_domains_p_pdaf(int* step, + int* n_domains_p) noexcept with gil: + """Get number of analysis domains. + + Parameters + ---------- + step: int + Current step + n_domains_p: int + Number of analysis domains. + + Returns + ------- + n_domains_p: int + Number of analysis domains. + """ + n_domains_p[0] = (init_n_domains_p_pdaf)(step[0], n_domains_p[0]) + + + + + +cdef void c__init_obs_l_pdaf(int* domain_p, int* step, int* dim_obs_l, + double* observation_l) noexcept with gil: + """Initialise observation vector for local analysis domain. + + Parameters + ---------- + domain_p: int + Current local domain index + step: int + Current time step + dim_obs_l: int + Local observation vector dimension. + observation_l: np.ndarray[np.float, dim=1] + Local observation vector. + + Returns + ------- + observation_l: np.ndarray[np.float, dim=1] + Local observation vector. + """ + cdef double[::1] observation_l_np = np.asarray( observation_l, order="F") + + observation_l_np = (init_obs_l_pdaf)(domain_p[0], step[0], + dim_obs_l[0], + observation_l_np.base) + + cdef double[::1] observation_l_new + if observation_l != &observation_l_np[0]: + observation_l_new = np.asarray( observation_l, order="F") + observation_l_new[...] = observation_l_np + warnings.warn("The memory address of observation_l is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__init_obsvar_l_pdaf(int* domain_p, int* step, int* dim_obs_l, + double* obs_l, int* dim_obs_p, double* meanvar_l) noexcept with gil: + """Get mean of analysis domain local observation variance. + + This is used by local adaptive forgetting factor (type_forget=2) + + Parameters + ---------- + domain_p: int + Current local domain index + step: int + Current time step + dim_obs_l: int + Local observation vector dimension. + obs_l: np.ndarray[np.float, dim=1] + Local observation vector. + dim_obs_p: int + Process-local observation vector dimension. + meanvar_l: float + Mean of analysis domain local observation variance. + + Returns + ------- + meanvar_l: float + Mean of analysis domain local observation variance. + """ + cdef double[::1] obs_l_np = np.asarray( obs_l, order="F") + + meanvar_l[0] = (init_obsvar_l_pdaf)(domain_p[0], step[0], + dim_obs_l[0], + obs_l_np.base, + dim_obs_p[0], meanvar_l[0]) + + + +cdef void c__init_obserr_f_pdaf(int* step, int* dim_obs_f, double* obs_f, + double* obserr_f) noexcept with gil: + """Initializes the full vector of observations error standard deviations. + + Parameters + ---------- + step : int + Current time step. + dim_obs_f : int + Full observation vector dimension. + obs_f : np.ndarray[np.float, dim=1] + Full observation vector. + obserr_f : np.ndarray[np.float, dim=1] + Full observation error vector. + + Returns + ------- + obserr_f : np.ndarray[np.float, dim=1] + Full observation error vector. + """ + cdef double[::1] obs_f_np = np.asarray( obs_f, order="F") + cdef double[::1] obserr_f_np = np.asarray( obserr_f, order="F") + + obserr_f_np = (init_obserr_f_pdaf)(step[0], dim_obs_f[0], + obs_f_np.base, obserr_f_np.base) + + cdef double[::1] obserr_f_new + if obserr_f != &obserr_f_np[0]: + obserr_f_new = np.asarray( obserr_f, order="F") + obserr_f_new[...] = obserr_f_np + warnings.warn("The memory address of obserr_f is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__l2g_state_pdaf(int* step, int* domain_p, int* dim_l, + double* state_l, int* dim_p, double* state_p) noexcept with gil: + """Assign local state vector to process-local global state vector. + + Parameters + ---------- + step: int + Current time step + domain_p: int + Current local domain index + dim_l: int + Local analysis domain state vector dimension. + state_l: np.ndarray[np.float, dim=1] + Local analysis domain state vector. + dim_p: int + Process-local global state vector dimension. + state_p: np.ndarray[np.float, dim=1] + Process-local global state vector. + + Returns + ------- + state_p: np.ndarray[np.float, dim=1] + Process-local global state vector. + """ + cdef double[::1] state_l_np = np.asarray( state_l, order="F") + cdef double[::1] state_p_np = np.asarray( state_p, order="F") + + state_p_np = (l2g_state_pdaf)(step[0], domain_p[0], dim_l[0], + state_l_np.base, dim_p[0], + state_p_np.base) + + cdef double[::1] state_p_new + if state_p != &state_p_np[0]: + state_p_new = np.asarray( state_p, order="F") + state_p_new[...] = state_p_np + warnings.warn("The memory address of state_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__prodrinva_l_pdaf(int* domain_p, int* step, int* dim_obs_l, + int* rank, double* obs_l, double* a_l, double* c_l) noexcept with gil: + """Provide :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l`. + + Here, one should do :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l`. + The matrix :math:`\mathbf{A}_l` depends on the filter algorithm. + + One can also perform observation localisation. This can be helped by the function + :func:`pyPDAF.PDAF.local_weight` to get the observation weight. + + Parameters + ---------- + domain_p: int + Current local domain index. + step: int + Current time step + dim_obs_l: int + Dimension of observation vector in local analysis domain + rank: int + Rank of the local analysis domain + The size of it dpends on the filter algorithms. + obs_l: np.ndarray[np.float, dim=1] + Observation vector in local analysis domain. shape: (dim_obs_l, ) + a_l: np.ndarray[np.float, dim=2] + Matrix A in local analysis domain. + shape: (dim_obs_l, rank) + c_l: np.ndarray[np.float, dim=2] + :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l` in local analysis domain. + shape: (dim_obs_l, rank) + + Returns + ------- + c_l: np.ndarray[np.float, dim=2] + :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l` in local analysis domain. + shape: (dim_obs_l, rank) + """ + cdef double[::1] obs_l_np = np.asarray( obs_l, order="F") + cdef double[::1,:] a_l_np = np.asarray( a_l, order="F") + cdef double[::1,:] c_l_np = np.asarray( c_l, order="F") + + a_l_np,c_l_np = (prodrinva_l_pdaf)(domain_p[0], step[0], + dim_obs_l[0], rank[0], + obs_l_np.base, a_l_np.base, + c_l_np.base) + + cdef double[::1,:] a_l_new + if a_l != &a_l_np[0,0]: + a_l_new = np.asarray( a_l, order="F") + a_l_new[...] = a_l_np + warnings.warn("The memory address of a_l is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + cdef double[::1,:] c_l_new + if c_l != &c_l_np[0,0]: + c_l_new = np.asarray( c_l, order="F") + c_l_new[...] = c_l_np + warnings.warn("The memory address of c_l is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__localize_covar_pdaf(int* dim_p, int* dim_obs, double* hp_p, + double* hph) noexcept with gil: + """Perform covariance localisation. + + This is only used for stochastic EnKF. The localisation is performed + for HP and HPH.T. + + This can be helped by function :func:`pyPDAF.PDAFomi.localize_covar`. + This is replaced by :func:`PDAFomi.set_localize_covar` in PDAF3. + + Parameters + ---------- + dim_p: int + Dimension of the state vector. + dim_obs: int + Dimension of the observation vector. + hp_p: np.ndarray[np.float, dim=2] + Matrix HP. Shape: (dim_obs, dim_p) + hph: np.ndarray[np.float, dim=2] + Matrix HPH.T. Shape: (dim_obs, dim_obs) + + Returns + ------- + hp_p: np.ndarray[np.float, dim=2] + Localised matrix HP. Shape: (dim_obs, dim_p) + hph: np.ndarray[np.float, dim=2] + Localised matrix HPH.T. Shape: (dim_obs, dim_obs) + """ + cdef double[::1,:] hp_p_np = np.asarray( hp_p, order="F") + cdef double[::1,:] hph_np = np.asarray( hph, order="F") + + hp_p_np,hph_np = (localize_covar_pdaf)(dim_p[0], dim_obs[0], + hp_p_np.base, hph_np.base) + + cdef double[::1,:] hp_p_new + if hp_p != &hp_p_np[0,0]: + hp_p_new = np.asarray( hp_p, order="F") + hp_p_new[...] = hp_p_np + warnings.warn("The memory address of hp_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + cdef double[::1,:] hph_new + if hph != &hph_np[0,0]: + hph_new = np.asarray( hph, order="F") + hph_new[...] = hph_np + warnings.warn("The memory address of hph is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__localize_covar_serial_pdaf(int* iobs, int* dim_p, + int* dim_obs, double* hp_p, double* hxy_p) noexcept with gil: + """Apply covariance localisation in EnSRF/EAKF. + + The localisation is applied to each observation element. The weight can be + obtained by :func:`pyPDAF.PDAF.local_weight`. + + Parameters + ---------- + iobs: int + Index of the observation element. + dim_p: int + Dimension of the state vector. + dim_obs: int + Dimension of the observation vector. + hp_p: np.ndarray[np.float, dim=1] + Matrix HP. Shape: (dim_p) + hph: np.ndarray[np.float, dim=1] + Matrix HPH.T. Shape: (dim_obs) + + Returns + ------- + hp_p: np.ndarray[np.float, dim=1] + Localised matrix HP. Shape: (dim_p) + hph: np.ndarray[np.float, dim=1] + Localised matrix HPH.T. Shape: (dim_obs) + """ + cdef double[::1] hp_p_np = np.asarray( hp_p, order="F") + cdef double[::1] hxy_p_np = np.asarray( hxy_p, order="F") + + hp_p_np,hxy_p_np = (localize_covar_serial_pdaf)(iobs[0], + dim_p[0], + dim_obs[0], + hp_p_np.base, + hxy_p_np.base) + + cdef double[::1] hp_p_new + if hp_p != &hp_p_np[0]: + hp_p_new = np.asarray( hp_p, order="F") + hp_p_new[...] = hp_p_np + warnings.warn("The memory address of hp_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + cdef double[::1] hxy_p_new + if hxy_p != &hxy_p_np[0]: + hxy_p_new = np.asarray( hxy_p, order="F") + hxy_p_new[...] = hxy_p_np + warnings.warn("The memory address of hxy_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__likelihood_pdaf(int* step, int* dim_obs_p, double* obs_p, + double* resid, double* likely) noexcept with gil: + """Compute the likelihood of the observation for a given ensemble member. + + The function is used with the nonlinear filter NETF and particle filter. The likelihood + depends on the assumed observation error distribution. + For a Gaussian observation error, the likelihood is + :math:`\exp(-0.5(\mathbf{y}-\mathbf{H}\mathbf{x})^\mathrm{T}R^{-1}(\mathbf{y}-\mathbf{H}\mathbf{x}))`. + The vector :math:`\mathbf{y}-\mathbf{H}\mathbf{x} = \mathrm{resid}` is + provided as an input argument. + + Parameters + ---------- + step: int + Current time step + dim_obs_p : int + Dimension of the observation vector. + obs_p: np.ndarray[np.float, dim=1] + Observation vector. Shape: (dim_obs_p) + resid: np.ndarray[np.float, dim=1] + Residual vector between observations and state. Shape: (dim_obs_p) + likely: float + Likelihood of the observation + + Returns + ------- + likely: float + Likelihood of the observation + """ + cdef double[::1] obs_p_np = np.asarray( obs_p, order="F") + cdef double[::1] resid_np = np.asarray( resid, order="F") + + likely[0] = (likelihood_pdaf)(step[0], dim_obs_p[0], + obs_p_np.base, resid_np.base, + likely[0]) + + + +cdef void c__likelihood_l_pdaf(int* domain_p, int* step, int* dim_obs_l, + double* obs_l, double* resid_l, double* likely_l) noexcept with gil: + """Compute the likelihood of the observation for a given ensemble member + according to the observations used for the local analysis. + + The function is used in the localized nonlinear filter LNETF. The likelihood + depends on the assumed observation error distribution. + For a Gaussian observation error, the likelihood is + :math:`\exp(-0.5(\mathbf{y}-\mathbf{H}\mathbf{x})^\mathrm{T}R^{-1}(\mathbf{y}-\mathbf{H}\mathbf{x}))`. + The vector :math:`\mathbf{y}-\mathbf{H}\mathbf{x} = \mathrm{resid}` is + provided as an input argument. + + This function is also the place to perform observation localisation. + To initialize a vector of weights, the routine :func:`pyPDAF.PDAF.local_weight` + can be called. + + Parameters + ---------- + domain_p: int + Current local analysis domain index + step: int + Current time step + dim_obs_l: int + Dimension of the local observation vector. + obs_l: np.ndarray[np.float, dim=1] + Observation vector. Shape: (dim_obs_l) + resid_l: np.ndarray[np.float, dim=1] + Residual vector between observations and state. Shape: (dim_obs_l) + likely_l: float + Likelihood of the local observation + + Returns + ------- + likely_l: float + Likelihood of the local observation + """ + cdef double[::1] obs_l_np = np.asarray( obs_l, order="F") + cdef double[::1] resid_l_np = np.asarray( resid_l, order="F") + + resid_l_np,likely_l[0] = (likelihood_l_pdaf)(domain_p[0], + step[0], + dim_obs_l[0], + obs_l_np.base, + resid_l_np.base, + likely_l[0]) + + cdef double[::1] resid_l_new + if resid_l != &resid_l_np[0]: + resid_l_new = np.asarray( resid_l, order="F") + resid_l_new[...] = resid_l_np + warnings.warn("The memory address of resid_l is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__get_obs_f_pdaf(int* step, int* dim_obs_f, + double* observation_f) noexcept with gil: + """Receive synthetic observations from PDAF. + + This function is used in twin experiments for observation generations. + One can, for example, save synthetic observations in this function. + + Parameters + ---------- + step: int + Current time step + dim_obs_f: int + Full observation vector dimension. + observation_f: np.ndarray[np.float, dim=1] + Full observation vector. + + Returns + ------- + observation_f: np.ndarray[np.float, dim=1] + Full observation vector. + """ + cdef double[::1] observation_f_np = np.asarray( observation_f, order="F") + + observation_f_np = (get_obs_f_pdaf)(step[0], dim_obs_f[0], + observation_f_np.base) + + cdef double[::1] observation_f_new + if observation_f != &observation_f_np[0]: + observation_f_new = np.asarray( observation_f, order="F") + observation_f_new[...] = observation_f_np + warnings.warn("The memory address of observation_f is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__cvt_adj_ens_pdaf(int* iter, int* dim_p, int* dim_ens, + int* dim_cv_ens_p, double* ens_p, double* vcv_p, + double* cv_p) noexcept with gil: + """The adjoint control variable transformation involving ensembles. + + Here, this function performs + :math:`\mathbf{U}^\mathrm{T} \mathbf{v}_h`. Here, the input vector can be + :math:`\mathbf{v}_h = \mathbf{H}^\mathrm{T}\mathbf{R}^{-1}\delta \mathbf{x}` + with :math:`\delta \mathbf{x}` the innovation vector. + + The control vector transform is given by :math:`\mathbf{U}\mathbf{v}` with + :math:`\mathbf{v}` the control vector and :math:`\mathbf{U}` the transformation + matrix, which can be :math:`\mathbf{B}^\frac{1}{2}`. + + This function is used in 3DEnVar and hybrid 3DVar. + + Parameters + ---------- + iter: int + Current optimisation iteration number. + dim_p: int + Dimension of the state vector. + dim_ens: int + Dimension of the ensemble. + dim_cv_ens_p: int + Dimension of the control vector. + ens_p: np.ndarray[np.float, dim=2] + Ensemble matrix. shape: (dim_p, dim_ens) + vcv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{v}_h`. shape: (dim_p, ) + cv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U}^\mathrm{T} \mathbf{v}_h`. shape: (dim_cv_ens_p, ) + + Returns + ------- + cv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U}^\mathrm{T} \mathbf{v}_h`. shape: (dim_cv_ens_p, ) + """ + cdef double[::1,:] ens_p_np = np.asarray( ens_p, order="F") + cdef double[::1] vcv_p_np = np.asarray( vcv_p, order="F") + cdef double[::1] cv_p_np = np.asarray( cv_p, order="F") + + cv_p_np = (cvt_adj_ens_pdaf)(iter[0], dim_p[0], dim_ens[0], + dim_cv_ens_p[0], ens_p_np.base, + vcv_p_np.base, cv_p_np.base) + + cdef double[::1] cv_p_new + if cv_p != &cv_p_np[0]: + cv_p_new = np.asarray( cv_p, order="F") + cv_p_new[...] = cv_p_np + warnings.warn("The memory address of cv_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__cvt_adj_pdaf(int* iter, int* dim_p, int* dim_cvec, + double* vcv_p, double* cv_p) noexcept with gil: + """The adjoint control variable transformation. + + Here, this function performs + :math:`\mathbf{U}^\mathrm{T} \mathbf{v}_h`. Here, the input vector can be + :math:`\mathbf{v}_h = \mathbf{H}^\mathrm{T}\mathbf{R}^{-1}\delta \mathbf{x}` + with :math:`\delta \mathbf{x}` the innovation vector. + + The control vector transform is given by :math:`\mathbf{U}\mathbf{v}` with + :math:`\mathbf{v}` the control vector and :math:`\mathbf{U}` the transformation + matrix, which can be :math:`\mathbf{B}^\frac{1}{2}`. + + This function is used in 3DVar and hybrid 3DVar. + + Parameters + ---------- + iter: int + Current optimisation iteration number. + dim_p: int + Dimension of the state vector. + dim_cvec: int + Dimension of the control vector. + vcv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{v}_h`. shape: (dim_p, ) + cv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U}^\mathrm{T} \mathbf{v}_h`. shape: (dim_cvec, ) + + Returns + ------- + cv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U}^\mathrm{T} \mathbf{v}_h`. shape: (dim_cvec, ) + """ + cdef double[::1] vcv_p_np = np.asarray( vcv_p, order="F") + cdef double[::1] cv_p_np = np.asarray( cv_p, order="F") + + cv_p_np = (cvt_adj_pdaf)(iter[0], dim_p[0], dim_cvec[0], + vcv_p_np.base, cv_p_np.base) + + cdef double[::1] cv_p_new + if cv_p != &cv_p_np[0]: + cv_p_new = np.asarray( cv_p, order="F") + cv_p_new[...] = cv_p_np + warnings.warn("The memory address of cv_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__cvt_pdaf(int* iter, int* dim_p, int* dim_cvec, double* cv_p, + double* vv_p) noexcept with gil: + """The control variable transformation. + + Here, this function performs :math:`\mathbf{U} \mathbf{v}` with + :math:`\mathbf{v}` the control vector and :math:`\mathbf{U}` the transformation + matrix, which can be :math:`\mathbf{B}^\frac{1}{2}`. + + This function is used in 3DVar and hybrid 3DVar. + + Parameters + ---------- + iter: int + Current optimisation iteration number. + dim_p: int + Dimension of the state vector. + dim_cvec: int + Dimension of the control vector. + cv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{v}`. shape: (dim_cvec, ) + vv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U} \mathbf{v}`. shape: (dim_p, ) + + Returns + ------- + vv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U} \mathbf{v}`. shape: (dim_p, ) + """ + cdef double[::1] cv_p_np = np.asarray( cv_p, order="F") + cdef double[::1] vv_p_np = np.asarray( vv_p, order="F") + + vv_p_np = (cvt_pdaf)(iter[0], dim_p[0], dim_cvec[0], + cv_p_np.base, vv_p_np.base) + + cdef double[::1] vv_p_new + if vv_p != &vv_p_np[0]: + vv_p_new = np.asarray( vv_p, order="F") + vv_p_new[...] = vv_p_np + warnings.warn("The memory address of vv_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__cvt_ens_pdaf(int* iter, int* dim_p, int* dim_ens, + int* dim_cvec_ens, double* ens_p, double* v_p, + double* vv_p) noexcept with gil: + """The control variable transformation involving ensembles. + + Here, this function performs :math:`\mathbf{U} \mathbf{v}` with + :math:`\mathbf{v}` the control vector and :math:`\mathbf{U}` the transformation + matrix, which can be :math:`\mathbf{B}^\frac{1}{2}`. + + This function is used in 3DEnVar and hybrid 3DVar. + + Parameters + ---------- + iter: int + Current optimisation iteration number. + dim_p: int + Dimension of the state vector. + dim_ens: int + Dimension of the ensemble. + dim_cv_ens_p: int + Dimension of the control vector. + ens_p: np.ndarray[np.float, dim=2] + Ensemble matrix. shape: (dim_p, dim_ens) + v_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{v}`. shape: (dim_cv_ens_p, ) + vv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U} \mathbf{v}`. shape: (dim_p, ) + + Returns + ------- + vv_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{U} \mathbf{v}`. shape: (dim_p, ) + """ + cdef double[::1,:] ens_p_np = np.asarray( ens_p, order="F") + cdef double[::1] v_p_np = np.asarray( v_p, order="F") + cdef double[::1] vv_p_np = np.asarray( vv_p, order="F") + + vv_p_np = (cvt_ens_pdaf)(iter[0], dim_p[0], dim_ens[0], + dim_cvec_ens[0], ens_p_np.base, + v_p_np.base, vv_p_np.base) + + cdef double[::1] vv_p_new + if vv_p != &vv_p_np[0]: + vv_p_new = np.asarray( vv_p, order="F") + vv_p_new[...] = vv_p_np + warnings.warn("The memory address of vv_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__obs_op_adj_pdaf(int* step, int* dim_p, int* dim_obs_p, + double* m_state_p, double* state_p) noexcept with gil: + """Apply adjoint observation operator + + This function computes :math:`\mathbf{H}^\mathrm{T} \mathbf{w}`, where + :math:`\mathbf{H}` is the observation operator and + :math:`\mathbf{w}` is a vector in observation space. + + Parameters + ---------- + step : int + Current step + dim_p : int + Dimension of state vector + dim_obs_p: int + Dimension of observation vector + m_state_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{w}`. shape: (dim_obs_p,) + state_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{H}^\mathrm{T} \mathbf{w}`. shape: (dim_p,) + + Returns + ------- + state_p: np.ndarray[np.float, dim=1] + :math:`\mathbf{H}^\mathrm{T} \mathbf{w}`. shape: (dim_p,) + """ + cdef double[::1] m_state_p_np = np.asarray( m_state_p, order="F") + cdef double[::1] state_p_np = np.asarray( state_p, order="F") + + state_p_np = (obs_op_adj_pdaf)(step[0], dim_p[0], dim_obs_p[0], + m_state_p_np.base, state_p_np.base) + + cdef double[::1] state_p_new + if state_p != &state_p_np[0]: + state_p_new = np.asarray( state_p, order="F") + state_p_new[...] = state_p_np + warnings.warn("The memory address of state_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__obs_op_lin_pdaf(int* step, int* dim_p, int* dim_obs_p, + double* state_p, double* m_state_p) noexcept with gil: + """Apply linearised observation operator + + This function computes :math:`\mathbf{H} \mathbf{x}`, where + :math:`\mathbf{H}` is the linearised observation operator and + :math:`\mathbf{x}` is state vector. + + Parameters + ---------- + step : int + Current step + dim_p : int + Dimension of state vector + dim_obs_p: int + Dimension of observation vector + state_p: np.ndarray[np.float, dim=1] + State vector. shape: (dim_p,) + m_state_p: np.ndarray[np.float, dim=1] + Observed state vector. shape: (dim_obs_p,) + + Returns + ------- + m_state_p: np.ndarray[np.float64, dim=1] + Observed state vector. shape: (dim_obs_p,) + """ + cdef double[::1] state_p_np = np.asarray( state_p, order="F") + cdef double[::1] m_state_p_np = np.asarray( m_state_p, order="F") + + m_state_p_np = (obs_op_lin_pdaf)(step[0], dim_p[0], + dim_obs_p[0], state_p_np.base, + m_state_p_np.base) + + cdef double[::1] m_state_p_new + if m_state_p != &m_state_p_np[0]: + m_state_p_new = np.asarray( m_state_p, order="F") + m_state_p_new[...] = m_state_p_np + warnings.warn("The memory address of m_state_p is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__likelihood_hyb_l_pdaf(int* domain_p, int* step, + int* dim_obs_l, double* obs_l, double* resid_l, double* gamma, + double* likely_l) noexcept with gil: + """Compute the likelihood of the observation for a given ensemble member + according to the observations used for the local analysis with hybrid weight. + + The function is used in the localized nonlinear filter LKNETF. The likelihood + depends on the assumed observation error distribution. + For a Gaussian observation error, the likelihood is + :math:`\exp(-0.5(\mathbf{y}-\mathbf{H}\mathbf{x})^\mathrm{T}R^{-1}(\mathbf{y}-\mathbf{H}\mathbf{x}))`. + The vector :math:`\mathbf{y}-\mathbf{H}\mathbf{x} = \mathrm{resid}` is + provided as an input argument. + + The hybrid weight `gamma` is used weight between LNETF and LETKF. which is applied + to :math:`R^{-1}(\mathbf{y}-\mathbf{H}\mathbf{x})`. + + This function is also the place to perform observation localisation. + To initialize a vector of weights, the routine :func:`pyPDAF.PDAF.local_weight` + can be called. + + Parameters + ---------- + domain_p: int + Current local analysis domain index + step: int + Current time step + dim_obs_l: int + Dimension of the local observation vector. + obs_l: np.ndarray[np.float, dim=1] + Observation vector. Shape: (dim_obs_l) + gamma: float + Hybrid weight provided by PDAF + resid_l: np.ndarray[np.float, dim=1] + Residual vector between observations and state. Shape: (dim_obs_l) + likely_l: float + Likelihood of the local observation + + Returns + ------- + likely_l: float + Likelihood of the local observation + + """ + cdef double[::1] obs_l_np = np.asarray( obs_l, order="F") + cdef double[::1] resid_l_np = np.asarray( resid_l, order="F") + + resid_l_np,likely_l[0] = (likelihood_hyb_l_pdaf)(domain_p[0], + step[0], + dim_obs_l[0], + obs_l_np.base, + resid_l_np.base, + gamma[0], + likely_l[0]) + + cdef double[::1] resid_l_new + if resid_l != &resid_l_np[0]: + resid_l_new = np.asarray( resid_l, order="F") + resid_l_new[...] = resid_l_np + warnings.warn("The memory address of resid_l is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + + +cdef void c__prodrinva_hyb_l_pdaf(int* domain_p, int* step, int* dim_obs_l, + int* rank, double* obs_l, double* gamma, double* a_l, + double* c_l) noexcept with gil: + """Provide :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l` with weighting. + + Here, one should do :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l`. + The matrix :math:`\mathbf{A}_l` depends on the filter algorithm. + + This function is used in LKNETF where `gamma` is multipled with `c_l` for + weighting between LETKF and LNETF. + + One can also perform observation localisation. This can be helped by the function + :func:`pyPDAF.PDAF.local_weight` to get the observation weight. + + Parameters + ---------- + domain_p: int + Current local domain index. + step: int + Current time step + dim_obs_l: int + Dimension of observation vector in local analysis domain + rank: int + Rank of the local analysis domain + The size of it dpends on the filter algorithms. + obs_l: np.ndarray[np.float, dim=1] + Observation vector in local analysis domain. shape: (dim_obs_l, ) + gamma: float + Hybrid weight provided by PDAF + a_l: np.ndarray[np.float, dim=2] + Matrix A in local analysis domain. shape: (dim_obs_l, rank) + c_l: np.ndarray[np.float, dim=2] + :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l` in local analysis domain. + shape: (dim_obs_l, rank) + + Returns + ------- + c_l: np.ndarray[np.float, dim=2] + :math:`\mathbf{R}^{-1}_l \times \mathbf{A}_l` in local analysis domain. + shape: (dim_obs_l, rank) + """ + + cdef double[::1] obs_l_np = np.asarray( obs_l, order="F") + cdef double[::1,:] a_l_np = np.asarray( a_l, order="F") + cdef double[::1,:] c_l_np = np.asarray( c_l, order="F") + + a_l_np,c_l_np = (prodrinva_hyb_l_pdaf)(domain_p[0], step[0], + dim_obs_l[0], + rank[0], + obs_l_np.base, gamma[0], + a_l_np.base, c_l_np.base) + + cdef double[::1,:] a_l_new + if a_l != &a_l_np[0,0]: + a_l_new = np.asarray( a_l, order="F") + a_l_new[...] = a_l_np + warnings.warn("The memory address of a_l is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) + cdef double[::1,:] c_l_new + if c_l != &c_l_np[0,0]: + c_l_new = np.asarray( c_l, order="F") + c_l_new[...] = c_l_np + warnings.warn("The memory address of c_l is changed in c__add_obs_err_pdaf." + "The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning) diff --git a/pyPDAF/source/src/pyPDAF/py.typed b/pyPDAF/source/src/pyPDAF/py.typed new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/pyPDAF/source/tests/test_example.py b/pyPDAF/source/tests/test_example.py new file mode 100644 index 0000000000000000000000000000000000000000..13d6fc707097320314185ca1a51901aeef0febe9 --- /dev/null +++ b/pyPDAF/source/tests/test_example.py @@ -0,0 +1,45 @@ +import numpy as np + +def test_ens_forecast(): + f_out_name = 'true_outputs_online/ens_{i_ens:02}_step{step:02}_for.txt' + py_out_name = 'ens_{i_ens}_step{step}_for.txt' + nt = 18 + n_ens = 4 + for step in range(1, nt, 2): + for i in range(n_ens): + f_out = np.loadtxt(f_out_name.format(i_ens=i+1, step=step+1)) + py_out = np.loadtxt(py_out_name.format(i_ens=i+1, step=step+1), delimiter=';') + assert np.allclose(f_out, py_out), 'Python output and Fortran ensemble forecast differs!' + +def test_ens_analysis(): + f_out_name = 'true_outputs_online/ens_{i_ens:02}_step{step:02}_ana.txt' + py_out_name = 'ens_{i_ens}_step{step}_ana.txt' + nt = 18 + n_ens = 4 + for step in range(1, nt, 2): + for i in range(n_ens): + f_out = np.loadtxt(f_out_name.format(i_ens=i+1, step=step+1)) + py_out = np.loadtxt(py_out_name.format(i_ens=i+1, step=step+1), delimiter=';') + assert np.allclose(f_out, py_out), 'Python output and Fortran ensemble analysis differs!' + +def test_state_analysis(): + f_out_name = 'true_outputs_online/state_step{step:02}_ana.txt' + py_out_name = 'state_step{step}_ana.txt' + nt = 18 + n_ens = 4 + for step in range(1, nt, 2): + for i in range(n_ens): + f_out = np.loadtxt(f_out_name.format(i_ens=i+1, step=step+1)) + py_out = np.loadtxt(py_out_name.format(i_ens=i+1, step=step+1), delimiter=';') + assert np.allclose(f_out, py_out), 'Python output and Fortran ensemble analysis mean differs!' + +def test_state_forecast(): + f_out_name = 'true_outputs_online/state_step{step:02}_for.txt' + py_out_name = 'state_step{step}_for.txt' + nt = 18 + n_ens = 4 + for step in range(1, nt, 2): + for i in range(n_ens): + f_out = np.loadtxt(f_out_name.format(i_ens=i+1, step=step+1)) + py_out = np.loadtxt(py_out_name.format(i_ens=i+1, step=step+1), delimiter=';') + assert np.allclose(f_out, py_out), 'Python output and Fortran ensemble forecast mean differs!' \ No newline at end of file diff --git a/pyPDAF/source/tests/test_init.py b/pyPDAF/source/tests/test_init.py new file mode 100644 index 0000000000000000000000000000000000000000..118ffb63a037326b6968de965ef55336f28d2fa5 --- /dev/null +++ b/pyPDAF/source/tests/test_init.py @@ -0,0 +1,126 @@ +import numpy as np +import mpi4py.MPI as MPI +import importlib +import pytest + + +def test_dim_ens_1(filter_type, subtype): + import pyPDAF.PDAF as PDAF + """Test the initialisation when # + dimension of `uinv` is (dim_ens - 1, dim_ens - 1). + """ + def init_ens_pdaf(filtertype:int, dim_p:int, dim_ens:int, + state_p:np.ndarray, uinv:np.ndarray, + ens_p:np.ndarray, status_pdaf:int + ) -> tuple[np.ndarray, np.ndarray, + np.ndarray, int]: + assert uinv.shape == (dim_ens - 1, dim_ens - 1), \ + f"Expected uinv.shape to be {(dim_ens - 1, dim_ens - 1)}"\ + f" but got {uinv.shape}" + return state_p, uinv, ens_p, status_pdaf + + dim_p = 20 + dim_ens = 4 + forget = 1.0 + + param_int = np.array([dim_p, dim_ens, ], dtype=np.intc) + param_float = np.array([forget, ]) + if filter_type == 200: + param_int = np.array([dim_p, dim_ens, 1, dim_p, dim_p], dtype=np.intc) + + _, _, status = PDAF.init(filter_type, + subtype, + 0, + param_int, param_float, + MPI.COMM_WORLD.py2f(), + MPI.COMM_WORLD.py2f(), + MPI.COMM_WORLD.py2f(), + 1, 1, True, + init_ens_pdaf, 0) + + +def test_dim_ens(filter_type, subtype): + import pyPDAF.PDAF as PDAF + """Test the initialisation when # + dimension of `uinv` is (dim_ens, dim_ens). + """ + def init_ens_pdaf(filtertype:int, dim_p:int, dim_ens:int, + state_p:np.ndarray, uinv:np.ndarray, + ens_p:np.ndarray, status_pdaf:int + ) -> tuple[np.ndarray, np.ndarray, + np.ndarray, int]: + assert uinv.shape == (dim_ens, dim_ens), \ + f"Expected uinv.shape to be {(dim_ens, dim_ens)}"\ + f" but got {uinv.shape}" + return state_p, uinv, ens_p, status_pdaf + + dim_p = 20 + dim_ens = 4 + forget = 1.0 + + param_int = np.array([dim_p, dim_ens, ], dtype=np.intc) + param_float = np.array([forget, ]) + if filter_type == 0: + param_float = np.array([forget, 1e-5]) + + _, _, status = PDAF.init(filter_type, + subtype, + 0, + param_int, + param_float, + MPI.COMM_WORLD.py2f(), + MPI.COMM_WORLD.py2f(), + MPI.COMM_WORLD.py2f(), + 1, 1, True, + init_ens_pdaf, 0) + + +def test_dim_1(filter_type, subtype): + import pyPDAF.PDAF as PDAF + """Test the initialisation when # + dimension of `uinv` is (1, 1). + """ + def init_ens_pdaf(filtertype:int, dim_p:int, dim_ens:int, + state_p:np.ndarray, uinv:np.ndarray, + ens_p:np.ndarray, status_pdaf:int + ) -> tuple[np.ndarray, np.ndarray, + np.ndarray, int]: + assert uinv.shape == (1, 1), \ + f"Expected uinv.shape to be {(1, 1)}"\ + f" but got {uinv.shape}" + return state_p, uinv, ens_p, status_pdaf + + dim_p = 20 + dim_ens = 4 + if filter_type == 200 and subtype == 0: + dim_ens = 1 + forget = 1.0 + + param_int = np.array([dim_p, dim_ens, ], dtype=np.intc) + param_float = np.array([forget, ]) + if filter_type == 0: + param_float = np.array([forget, 1e-5]) + + _, _, status = PDAF.init(filter_type, + subtype, + 0, + param_int, + param_float, + MPI.COMM_WORLD.py2f(), + MPI.COMM_WORLD.py2f(), + MPI.COMM_WORLD.py2f(), + 1, 1, True, + init_ens_pdaf, 0) + +import sys +filter_type = int(sys.argv[1]) +subtype = int(sys.argv[2]) +if filter_type in [1, 3, 6, 7, 200, 200, 200, 200]: + if filter_type == 200 and subtype != 0: + test_dim_ens_1(filter_type, subtype) +if filter_type in [0, 4, 5, 9, 10, 11]: + test_dim_ens(filter_type, subtype) +if filter_type in [2, 8, 12, 100, 200]: + if filter_type == 200 and subtype == 0: + test_dim_1(filter_type, subtype) + diff --git a/pyPDAF/source/tests/test_init.sh b/pyPDAF/source/tests/test_init.sh new file mode 100644 index 0000000000000000000000000000000000000000..b1039d37e9ebab3c4b69b6a64b36d5cded82db32 --- /dev/null +++ b/pyPDAF/source/tests/test_init.sh @@ -0,0 +1,127 @@ +#!/bin/bash +# testing the array size in Python +for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 100; +do + for j in 0 1 2 3 4 5; + do + if [ $i -eq 0 ] && [ $j -eq 4 ]; then + continue + fi + if [ $i -eq 2 ] && ([ $j -eq 2 ] || [ $j -eq 3 ] || [ $j -eq 4 ]); then + continue + fi + if [ $i -eq 3 ] && ([ $j -eq 1 ] || [ $j -eq 4 ]); then + continue + fi + if [ $i -eq 4 ] && [ $j -eq 4 ]; then + continue + fi + if [ $i -eq 5 ] && ([ $j -eq 1 ] || [ $j -eq 4 ]); then + continue + fi + if [ $i -eq 6 ] && ([ $j -eq 1 ] || [ $j -eq 4 ]); then + continue + fi + if [ $i -eq 7 ] && ([ $j -eq 1 ] || [ $j -eq 4 ]); then + continue + fi + if [ $i -eq 8 ] && ([ $j -eq 1 ] || [ $j -eq 2 ] || [ $j -eq 3 ] || [ $j -eq 4 ]); then + continue + fi + if [ $i -eq 9 ] && ([ $j -eq 1 ] || [ $j -eq 2 ] || [ $j -eq 3 ] || [ $j -eq 4 ]); then + continue + fi + if [ $i -eq 10 ] && ([ $j -eq 1 ] || [ $j -eq 2 ] || [ $j -eq 3 ] || [ $j -eq 4 ]); then + continue + fi + if [ $i -eq 11 ] && ([ $j -eq 2 ] || [ $j -eq 3 ]); then + continue + fi + if [ $i -eq 12 ] && ([ $j -eq 1 ] || [ $j -eq 2 ] || [ $j -eq 3 ] || [ $j -eq 4 ]); then + continue + fi + if [ $i -eq 100 ] && ([ $j -eq 1 ] || [ $j -eq 2 ] || [ $j -eq 3 ] || [ $j -eq 4 ] || [ $j -eq 5 ]); then + continue + fi + /home/ia923171/miniconda3/envs/pypdaf-devel/bin/python \ + test_init.py $i $j + done +done + +for i in 0 1 4 5 6 7; +do + /home/ia923171/miniconda3/envs/pypdaf-devel/bin/python \ + test_init.py 200 $i +done + +# testing the array size in Fortran +for i in 1 3 6 7; +do + for j in 0 1 2 3 4 5; + do + if [ $i -eq 3 ] && ([ $j -eq 1 ] || [ $j -eq 4 ]); then + continue + fi + if [ $i -eq 6 ] && ([ $j -eq 1 ] || [ $j -eq 4 ]); then + continue + fi + if [ $i -eq 7 ] && ([ $j -eq 1 ] || [ $j -eq 4 ]); then + continue + fi + ./test_init $i $j + done +done + +for i in 1 4 6 7; +do + ./test_init 200 $i +done + +for i in 0 4 5 9 10 11; +do + for j in 0 1 2 3 4 5; + do + if [ $i -eq 0 ] && [ $j -eq 4 ]; then + continue + fi + if [ $i -eq 4 ] && [ $j -eq 4 ]; then + continue + fi + if [ $i -eq 5 ] && ([ $j -eq 1 ] || [ $j -eq 4 ]); then + continue + fi + if [ $i -eq 9 ] && ([ $j -eq 1 ] || [ $j -eq 2 ] || [ $j -eq 3 ] || [ $j -eq 4 ]); then + continue + fi + if [ $i -eq 10 ] && ([ $j -eq 1 ] || [ $j -eq 2 ] || [ $j -eq 3 ] || [ $j -eq 4 ]); then + continue + fi + if [ $i -eq 11 ] && ([ $j -eq 2 ] || [ $j -eq 3 ]); then + continue + fi + ./test_init $i $j + done +done + +for i in 2 8 12 100 200; +do + for j in 0 1 2 3 4 5; + do + if [ $i -eq 2 ] && ([ $j -eq 2 ] || [ $j -eq 3 ] || [ $j -eq 4 ]); then + continue + fi + if [ $i -eq 8 ] && ([ $j -eq 1 ] || [ $j -eq 2 ] || [ $j -eq 3 ] || [ $j -eq 4 ]); then + continue + fi + if [ $i -eq 12 ] && ([ $j -eq 1 ] || [ $j -eq 2 ] || [ $j -eq 3 ] || [ $j -eq 4 ]); then + continue + fi + if [ $i -eq 100 ] && ([ $j -eq 1 ] || [ $j -eq 2 ] || [ $j -eq 3 ] || [ $j -eq 4 ] || [ $j -eq 5 ]); then + continue + fi + if [ $i -eq 200 ] && ([ $j -eq 1 ] || [ $j -eq 2 ] || [ $j -eq 3 ] || [ $j -eq 4 ] || [ $j -eq 5 ]); then + continue + fi + ./test_init $i $j + done +done diff --git a/pyPDAF/source/tool/cfi_binding.pxd b/pyPDAF/source/tool/cfi_binding.pxd new file mode 100644 index 0000000000000000000000000000000000000000..6d49ae2d008d0b8a28f7b0a120d246a4c1825293 --- /dev/null +++ b/pyPDAF/source/tool/cfi_binding.pxd @@ -0,0 +1,38 @@ +from libc.stdint cimport int8_t, int16_t +from libc.stddef cimport ptrdiff_t + +cdef extern from "ISO_Fortran_binding.h": + """ + typedef CFI_CDESC_T(1) CFI_cdesc_rank1; + typedef CFI_CDESC_T(2) CFI_cdesc_rank2; + typedef CFI_CDESC_T(3) CFI_cdesc_rank3; + """ + ctypedef ptrdiff_t CFI_index_t; + ctypedef int8_t CFI_rank_t; + ctypedef int8_t CFI_attribute_t; + ctypedef int16_t CFI_type_t; + + ctypedef struct CFI_dim_t: + CFI_index_t extent; + + ctypedef struct CFI_cdesc_t: + void *base_addr; + CFI_rank_t rank; + CFI_attribute_t attribute; + CFI_dim_t* dim; + + ctypedef CFI_cdesc_t CFI_cdesc_rank1; + ctypedef CFI_cdesc_t CFI_cdesc_rank2; + ctypedef CFI_cdesc_t CFI_cdesc_rank3; + + cdef int CFI_attribute_pointer; + cdef int CFI_attribute_allocatable; + cdef int CFI_attribute_other; + + cdef CFI_type_t CFI_type_double; + cdef CFI_type_t CFI_type_int; + + cdef extern void *CFI_address (const CFI_cdesc_t *, const CFI_index_t*) noexcept nogil; + cdef extern int CFI_establish(CFI_cdesc_t *, void *, CFI_attribute_t, + CFI_type_t, size_t, CFI_rank_t, const CFI_index_t*) noexcept nogil; + diff --git a/pyPDAF/source/tool/compare_subroutines.py b/pyPDAF/source/tool/compare_subroutines.py new file mode 100644 index 0000000000000000000000000000000000000000..8aae8bb3d72cb0ddc7131d497111adae8070c8a8 --- /dev/null +++ b/pyPDAF/source/tool/compare_subroutines.py @@ -0,0 +1,110 @@ +import os +import re + +def preprocess_fortran_file(file_path): + with open(file_path, 'r', encoding='utf-8', errors='ignore') as f: + lines = f.readlines() + + merged_lines = [] + current_line = "" + + for line in lines: + stripped = line.strip() + if "!" in stripped: + code_part, comment_part = stripped.split("!", 1) + stripped = code_part.strip() + if stripped.endswith("&"): + current_line += stripped[:-1] + " " + elif stripped.startswith("&"): + current_line += stripped[1:] + " " + else: + current_line += stripped + merged_lines.append(current_line) + current_line = "" + + return merged_lines + +def extract_subroutines_from_dir(path): + subroutine_signatures = set() + + for root, _, files in os.walk(path): + for file in files: + if file.lower().endswith(('.f90', '.f', '.f95', '.f03', '.f08')): + if file == 'pdaf_c_f_interface.f90': + continue + full_path = os.path.join(root, file) + lines = preprocess_fortran_file(full_path) + + interface_depth = 0 + + for line in lines: + # Entering an INTERFACE or ABSTRACT INTERFACE + if re.match(r'\s*(abstract\s+)?interface\b', line, re.I): + interface_depth += 1 + continue + + # Leaving an INTERFACE block + if re.match(r'\s*end\s+interface\b', line, re.I): + if interface_depth > 0: + interface_depth -= 1 + continue + + if interface_depth != 0: continue + match = re.search(r'\bsubroutine\s+([a-zA-Z0-9_]+)\s*\(([^)]*)\)', line, re.IGNORECASE) + if match: + name = match.group(1).lower() + args = match.group(2).replace(" ", "").lower() + signature = f"{name}({args})" + # removing c__ in pyPDAF c binding files + if name[:3] == 'c__': + signature = signature[3:] + # replace thisobs_l and thisobs with i_obs + if 'thisobs_l,thisobs' in signature: + signature = signature.replace('thisobs_l,thisobs', 'i_obs') + if 'thisobs,thisobs_l' in signature: + signature = signature.replace('thisobs,thisobs_l', 'i_obs') + if 'thisobs_l' in signature: + signature = signature.replace('thisobs_l', 'i_obs') + if 'thisobs' in signature: + signature = signature.replace('thisobs', 'i_obs') + subroutine_signatures.add(signature) + + return subroutine_signatures + +def compare_subroutines(dir_old, dir_new): + old_subs = extract_subroutines_from_dir(dir_old) + new_subs = extract_subroutines_from_dir(dir_new) + # new_subs = set() + + # print (old_subs) + + # for sub in new_subs: + # if 'pdaf3_assim_offline(' in sub: + # print(f"New subroutine found: {sub}") + + # for sub in old_subs: + # if 'pdaf3_assim_offline(' in sub: + # print(f"Old subroutine found: {sub}") + + added = new_subs - old_subs + removed = old_subs - new_subs + unchanged = old_subs & new_subs + + return added, removed, unchanged + +if __name__ == "__main__": + added, removed, unchanged = compare_subroutines('src/fortran', + 'PDAF/src') + + print("\n--- Added Subroutines ---") + for sig in sorted(added): + print(sig) + + print("\n--- Removed Subroutines ---") + for sig in sorted(removed): + print(sig) + + print(f"\n--- Summary ---") + print(f"Added: {len(added)}") + print(f"Removed: {len(removed)}") + print(f"Unchanged: {len(unchanged)}") diff --git a/pyPDAF/source/tool/docstring/__init__.py b/pyPDAF/source/tool/docstring/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c762381068953bf339f44efd6bde95af408587a9 --- /dev/null +++ b/pyPDAF/source/tool/docstring/__init__.py @@ -0,0 +1 @@ +#docstring diff --git a/pyPDAF/source/tool/docstring/docstrings.py b/pyPDAF/source/tool/docstring/docstrings.py new file mode 100644 index 0000000000000000000000000000000000000000..371938cf8422257b600b0898c43fa81e1422c713 --- /dev/null +++ b/pyPDAF/source/tool/docstring/docstrings.py @@ -0,0 +1,876 @@ +"""Generate API docstrings for pyPDAF functions +""" +from .pdaf_assimilate_docstrings import docstrings as assimilate_docstrings +from .pdaf_diag_docstrings import docstrings as diag_docstrings +from .pdaf_put_state_docstrings import docstrings as put_state_docstrings +from .pdaflocal_assimilate_docstrings import docstrings as local_assimilate_docstrings +from .pdaflocalomi_assimilate_docstrings import docstrings as localomi_assimilate_docstrings +from .pdaflocalomi_put_state_docstrings import docstrings as localomi_put_state_docstrings +from .pdafomi_assimilate_docstrings import docstrings as omi_assimilate_docstrings +from .pdafomi_put_state_docstrings import docstrings as omi_put_state_docstrings + +docstrings = {**assimilate_docstrings, **diag_docstrings, ** + put_state_docstrings, **local_assimilate_docstrings, ** + localomi_assimilate_docstrings, **localomi_put_state_docstrings, + **omi_assimilate_docstrings, **omi_put_state_docstrings} + + +docstrings['deallocate'] = \ + "Finalise the PDAF systems\n " \ + "including freeing some of\n " \ + "the memory used by PDAF.\n\n " \ + "This function cannot be used to\n " \ + "free all allocated PDAF memory.\n " \ + "Therefore, one should not use\n " \ + ":func:`pyPDAF.PDAF.init` afterwards." + +docstrings['eofcovar'] = \ + "EOF analysis of an ensemble of state vectors " \ + "by singular value decomposition.\n\n " \ + "Typically, this function is used with" \ + "\n " \ + ":func:`pyPDAF.PDAF.SampleEns`\n " \ + "to generate an ensemble of a chosen size \n " \ + "(up to the number of EOFs plus one).\n\n " \ + "Here, the function performs a singular value decomposition" \ + "\n " \ + "of the ensemble anomaly of the input matrix,\n " \ + "which is usually an ensemble formed by state vectors" \ + "\n " \ + "at multiple time steps.\n " \ + "The singular values and corresponding singular vectors" \ + "\n " \ + "can be used to\n " \ + "construct a covariance matrix.\n " \ + "This can be used as the initial error covariance" \ + "\n " \ + "for the initial ensemble.\n\n " \ + "A multivariate scaling can be performed to ensure that " \ + "all fields in the state vectors have unit variance.\n\n " \ + "It can be useful to store more EOFs than one finally\n " \ + "might want to use to have the flexibility\n " \ + "to carry the ensemble size.\n\n\n " \ + "See Also\n " \ + "--------\n " \ + "`PDAF webpage `_" + +docstrings['gather_dim_obs_f'] = \ + "Gather the dimension of observation vector\n " \ + "across multiple local domains/filter processors.\n\n " \ + "This function is typically used in deprecated PDAF functions" \ + "\n " \ + "without OMI.\n\n " \ + "This function can be used in the user-supplied function of" \ + "\n " \ + ":func:`py__init_dim_obs_f_pdaf`,\n " \ + "but it is recommended to use :func:`pyPDAF.PDAF.omi_gather_obs`" \ + "\n " \ + "with OMI.\n\n " \ + "This function does two things:\n " \ + " 1. Receiving observation dimension on each local process." \ + "\n " \ + " 2. Gather the total dimension of observation\n " \ + " across local process and the displacement of PE-local" \ + "\n " \ + " observations relative to the total observation vector" \ + "\n\n " \ + "The dimension of observations are used to allocate observation" \ + "\n " \ + "arrays. Therefore, it must be used before\n " \ + ":func:`pyPDAF.PDAF.gather_obs_f` or\n " \ + ":func:`pyPDAF.PDAF.gather_obs_f2`." + +docstrings['gather_obs_f'] = \ + "In the local filters (LESKTF, LETKF, LSEIK, LNETF) " \ + "this function returns the total observation vector " \ + "from process-local observations. " \ + "The function depends on " \ + "`pyPDAF.PDAF.gather_dim_obs_f` which defines the process-local observation dimensions. " \ + "Further, the related routine `pyPDAF.PDAF.gather_obs_f2` is used to\n " \ + "gather the associated 2D observation coordinates\n " + +docstrings['gather_obs_f2'] = \ + "In the local filters (LESKTF, LETKF, LSEIK, LNETF)\n " \ + "this function returns the full observation coordinates " \ + "from process-local observation coordinates. " \ + "The function depends on " \ + "`pyPDAF.PDAF.gather_dim_obs_f` which defines the process-local observation dimensions. " \ + "Further, the related routine `pyPDAF.PDAF.gather_obs_f` is used to " \ + "gather the associated observation vectors. \n \n " \ + "The routine is typically used in the routines `py__init_dim_obs_f_pdaf` " \ + "if the analysis step of the local filters is parallelized." + +docstrings['get_assim_flag'] = \ + "Return the flag that\n " \ + "indicates if the DA is performed in the last time step.\n " \ + "It only works for online DA systems. " + +docstrings['get_ensstats'] = \ + "Return the skewness and kutosis used in LKNETF. " + +docstrings['get_localfilter'] = \ + "Return whether a local filter is used. " + +docstrings['get_memberid'] = \ + "Return the ensemble member id on the current process.\n\n " \ + "For example, it can be called during the ensemble\n " \ + "integration if ensemble-specific forcing is read.\n " \ + "It can also be used in the user-supplied functions\n " \ + "such as :func:`py__collect_state_pdaf` and\n " \ + ":func:`py__distribute_state_pdaf`." + +docstrings['get_obsmemberid'] = \ + "Return the ensemble member id\n " \ + "when observation operator is being applied.\n\n " \ + "This function is used specifically for\n " \ + "user-supplied function :func:`py__obs_op_pdaf`." + +docstrings['get_smootherens'] = \ + "Return the smoothed ensemble in earlier time steps.\n\n " \ + "It is only used when the smoother options is used ." + +docstrings['get_state'] = \ + "Distribute analysis state vector to an array.\n\n " \ + "The primary purpose of this function is to distribute\n " \ + "the analysis state vector to the model.\n " \ + "This is attained by the user-supplied function\n " \ + ":func:`py__distribute_state_pdaf`.\n " \ + "One can also use this function to get the state vector\n " \ + "for other purposes, e.g. to write the state vector to a file." \ + "\n\n " \ + "In this function, the user-supplied function\n " \ + ":func:`py__next_observation_pdaf` is executed\n " \ + "to specify the number of forecast time steps\n " \ + "until the next assimilation step.\n " \ + "One can also use the user-supplied function to\n " \ + "end the assimilation.\n\n " \ + "In an online DA system, this function also execute\n " \ + "the user-supplied function :func:`py__prepoststep_state_pdaf`," \ + "\n " \ + "when this function is first called. The purpose of this design" \ + "\n " \ + "is to call this function right after :func:`pyPDAF.PDAF.init`" \ + "\n " \ + "to process the initial ensemble before using it to\n " \ + "initialse model forecast. This user-supplied function\n " \ + "will not be called afterwards.\n\n " \ + "This function is also used in flexible parallel system\n " \ + "where the number of ensemble members are greater than\n " \ + "the parallel model tasks. In this case, this function\n " \ + "is called multiple times to distribute the analysis ensemble." \ + "\n\n " \ + "User-supplied function are executed in the following sequence:" \ + "\n\n " \ + " 1. py__prepoststep_state_pdaf\n " \ + " (only in online system when first called)\n " \ + " 2. py__distribute_state_pdaf\n " \ + " 3. py__next_observation_pdaf" + +docstrings['init'] = \ + "Initialise the PDAF system.\n\n " \ + "It is called once at the beginning of the assimilation.\n\n " \ + "The function specifies the type of DA methods,\n " \ + "parameters of the filters, the MPI communicators,\n " \ + "and other parallel options.\n " \ + "The filter options including `filtertype`, `subtype`,\n " \ + "`param_int`, and `param_real`\n " \ + "are introduced in\n " \ + "`PDAF filter options wiki page" \ + " `_." \ + "\n " \ + "Note that the size of `param_int` and `param_real` depends on" \ + "\n " \ + "the filter type and subtype. However, for most filters,\n " \ + "they require at least the state vector size and ensemble size" \ + "\n " \ + "for `param_int`, and the forgetting factor for `param_real`." \ + "\n\n " \ + "The MPI communicators asked by this function depends on\n " \ + "the parallelisation strategy.\n " \ + "For the default parallelisation strategy, the user\n " \ + "can use the parallelisation module\n " \ + "provided under in `example directory " \ + "`_\n " \ + "without modifications.\n " \ + "The parallelisation can differ based on online and offline cases.\n " \ + "Users can also refer to `parallelisation documentation " \ + "`_ for\n " \ + "explanations or modifications.\n\n " \ + "This function also asks for a user-supplied function\n " \ + ":func:`py__init_ens_pdaf`.\n " \ + "This function is designed to provides an initial ensemble\n " \ + "to the internal PDAF ensemble array.\n " \ + "The internal PDAF ensemble then can be distributed to\n " \ + "initialise the model forecast using\n " \ + ":func:`pyPDAF.PDAF.get_state`.\n " \ + "This user-supplied function can be empty if the model\n " \ + "has already read the ensemble from restart files." \ + + +docstrings['local_weight'] = \ + "Get localisation weight for given distance,\n " \ + "cut-off radius, support radius, weighting type,\n " \ + "and weighting function.\n\n " \ + "This function is used in the analysis step of a filter\n " \ + "to computes a localisation weight.\n\n " \ + "Typically, in domain-localised filters, the function\n " \ + "is called in user-supplied :func:`py__prodRinvA_l_pdaf`.\n " \ + "In LEnKF, this function is called\n " \ + "in user-supplied :func:`py__localize_covar_pdaf`.\n\n " \ + "This function is usually only used without PDAF-OMI." + +docstrings['print_info'] = \ + "Print the wallclock time and memory measured by PDAF.\n\n " \ + "This should be called at the end of the DA program." + +docstrings['reset_forget'] = \ + "Reset the forgetting factor manually\n " \ + "during the assimilation process.\n\n " \ + "For the local ensemble Kalman filters\n " \ + "the forgetting factor can be set either globally\n " \ + "if this function is called outside of the loop over\n " \ + "local domains,\n " \ + "or\n " \ + "the forgetting factor can be set differently\n " \ + "for each local analysis domain within the loop over\n " \ + "local domains.\n\n " \ + "For the LNETF and the global filters\n " \ + "only a global setting of the forgeting factor is possible.\n " \ + "In addition, the implementation of adaptive choices\n " \ + "for the forgetting factor (beyond what is implemented in PDAF) are possible." + +docstrings['SampleEns'] = \ + "Generate an ensemble from singular values and\n " \ + "their vectors (EOF modes) of an ensemble anomaly matrix.\n\n " \ + "The singular values and vectors are derived from\n " \ + "the ensemble anomalies. This ensemble anomaly can be\n " \ + "obtained from a time anomaly of a model trajectory using\n " \ + ":func:`pyPDAF.PDAF.eofcovar`." + +docstrings['set_debug_flag'] = \ + "Activate the debug output of the PDAF.\n\n " \ + "Starting from the use of this function,\n " \ + "the debug infomation is sent to screen output.\n " \ + "The screen output end when the debug flag is\n " \ + "set to 0 by this function.\n\n " \ + "For the sake of simplicity,\n " \ + "we recommend using debugging output for\n " \ + "a single local domain, e.g.\n " \ + "`if domain_p == 1: pyPDAF.PDAF.set_debug_flag(1)`" + +docstrings['set_ens_pointer'] = \ + "Return the ensemble in a numpy array.\n\n " \ + "Here the internal array data has the same memoery address\n " \ + "as PDAF ensemble array allowing for manual ensemble modification." + +docstrings['set_smootherens'] = \ + "Get a pointer to smoother ensemble.\n\n " \ + "When smoother is used, the smoothed ensemble states\n " \ + "at earlier times are stored in an internal array of PDAF.\n " \ + "To be able to smooth post times,\n " \ + "the smoother algorithm must have access to the past ensembles.\n\n " \ + "In this function, the user can obtain a numpy array of\n " \ + "smoother ensemble. This array has the same memory address\n " \ + "as the internal PDAF smoother ensemble array.\n " \ + "This allows for manual modification of the smoother ensemble.\n\n " \ + "In the offline mode the user has to manually\n " \ + "fill the smoother ensemble array\n " \ + "from ensembles read in from files.\n " \ + "This function is typically called in\n " \ + ":func:`py__init_ens_pdaf` in the call to\n " \ + ":func:`pyPDAF.PDAF.PDAF_init`.\n\n " \ + "In the online mode, the smoother array is filled\n " \ + "automatically during the cycles of forecast phases and analysis steps." + +docstrings['seik_TtimesA'] = \ + "Perform matrix calculation of B = TA.\n\n " \ + "In this function, the input matrix A is\n " \ + "left multiplies by a matrix T.\n " \ + "The T matrix is\n " \ + r".. math::""\n\n " \ + r" M = \begin{bmatrix}""\n " \ + r" 1 - \frac{1}{N} & - \frac{1}{N} & \dots & - \frac{1}{N} & - \frac{1}{N} \\""\n " \ + r" - \frac{1}{N} & 1 - \frac{1}{N} & \dots & - \frac{1}{N} & - \frac{1}{N} \\""\n " \ + r" \dots & \dots & \dots & \dots & \dots \\""\n " \ + r" - \frac{1}{N} & - \frac{1}{N} & \dots & 1 - \frac{1}{N} & \dots \\""\n " \ + r" - \frac{1}{N} & - \frac{1}{N} & \dots & - \frac{1}{N} & - \frac{1}{N} \\""\n " \ + r" \end{bmatrix}" \ + "\n\n " \ + "In the context of the SEIK filter, this operation\n " \ + "is partially the second term of Eq. (23) in [1]_\n " \ + "and the T matrix is in Eq. (15)" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345. doi:10.1175/MWR-D-11-00102.1" + +docstrings['etkf_Tleft'] = \ + "Remove column mean (ensemble mean).\n\n " \ + "This function provides the ensemble anomaly of matrix A\n " \ + "if it is an ensemble of state vectors.\n " \ + "This function partially performs the second term of\n " \ + "Eq. (34) with T defined as Eq. (31) in [1]_." \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345. doi:10.1175/MWR-D-11-00102.1" + +docstrings['estkf_OmegaA'] = \ + "Get left Householder transformation of A.\n\n "\ + "This function partially performs the second term of Eq. (29)\n " \ + "and the Householder matrix Omega is given in Eq. (24) in [1]_." \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345. doi:10.1175/MWR-D-11-00102.1" + +docstrings['enkf_omega'] = \ + "Generate a random matrix with orthogonal basis.\n\n " \ + "This function generates the random matrix sampled\n " \ + "from standard Gaussian distribution with different scaling options." + +docstrings['seik_omega'] = \ + "Generate a random matrix with orthogonal basis.\n\n " \ + "This function generates a uniform orthogonal matrix\n " \ + "by iteratively applying Householder transformations.\n " \ + "In this matrix, each column is orthogonal to the previous ones." \ + "\n " \ + "This algorithm is documented in appendix of [1]_." \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345. doi:10.1175/MWR-D-11-00102.1" + +docstrings['incremental'] = \ + "Apply analysis increment to model state\n " \ + "in model forecast phase.\n\n " \ + "This function calls a user-supplied function\n " \ + "to utilise the analysis increment stored by PDAF in the model.\n " \ + "This may also be used for diagnostics purposes." + +docstrings['add_increment'] = \ + "Add analysis increment stored by PDAF to given state vector." + +docstrings['local_weights'] = \ + "Get a vector of localisation weights for given distances,\n " \ + "cut-off radius, support radius, weighting type,\n " \ + "and weighting function.\n\n " \ + "This function is used in the analysis step of a filter\n " \ + "to computes a localisation weight.\n\n " \ + "Typically, in domain-localised filters, the function\n " \ + "is called in user-supplied :func:`py__prodRinvA_l_pdaf`.\n " \ + "In LEnKF, this function is called\n " \ + "in user-supplied :func:`py__localize_covar_pdaf`.\n\n " \ + "This function is usually only used without PDAF-OMI.\n\n " \ + "This function is a vectorised version of\n " \ + ":func:`pyPDAF.PDAF.local_weight` without any regulations." + +docstrings['force_analysis'] = \ + "Perform assimilation after this function call.\n\n " \ + "This function overwrite member index of the ensemble state\n " \ + "by local_dim_ens (number of ensembles for current process,\n " \ + "in full parallel setup, this is 1.) and the counter\n " \ + "cnt_steps by nsteps-1.\n " \ + "This forces that the analysis step is executed at\n " \ + "the next call to PDAF assimilation functions." + +docstrings['gather_obs_f2_flex'] = \ + "Gather full observation coordinates from processor\n " \ + "local observation coordinates without PDAF-internal info.\n\n " \ + "In the local filters (LESKTF, LETKF, LSEIK, LNETF)\n " \ + "this function returns the full observation coordinates\n " \ + "from process-local observation coordinates.\n\n " \ + "This function has a similar functionality as\n " \ + ":func:`pyPDAF.PDAF.gather_obs_f2`, but it does not depend\n " \ + "on PDAF-internal observation dimension information,\n " \ + "which is specified once :func:`pyPDAF.PDAF.gather_dim_obs_f`\n " \ + "is executed.\n\n " \ + "This function can also be used as a generic function\n " \ + "to gather any 2D arrays\n " \ + "where the second dimension should be concatenated." + +docstrings['gather_obs_f_flex'] = \ + "Gather full observation from processor\n " \ + "local observation without PDAF-internal info.\n\n " \ + "In the local filters (LESKTF, LETKF, LSEIK, LNETF)\n " \ + "this function returns the full observation\n " \ + "from process-local observation.\n\n " \ + "This function has a similar functionality as\n " \ + ":func:`pyPDAF.PDAF.gather_obs_f`, but it does not depend\n " \ + "on PDAF-internal observation dimension information,\n " \ + "which is specified once :func:`pyPDAF.PDAF.gather_dim_obs_f`\n " \ + "is executed.\n\n " \ + "This function can also be used as a generic function\n " \ + "to gather any 2D arrays\n " \ + "where the second dimension should be concatenated." + + +docstrings['prepost'] = \ + "Perform pre-/post-processing.\n\n " \ + "This is designed similar to a DA method subroutine\n " \ + "where the ensemble/state vector collection, processing,\n " \ + "and distribution are all depending on user-supplied functions." \ + "\n\n " \ + "Compared to `pyPDAF.PDAF.assimilate_prepost`,\n " \ + "this function does not set assimilation flag.\n\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.put_state_prepost`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "The user-supplied function is executed as follows:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__prepoststep_state_pdaf\n " \ + " 4. py__distribute_state_pdaf\n " \ + " 5. py__next_observation_pdaf" + +docstrings['set_memberid'] = \ + "Set the ensemble member index to given value." + +docstrings['set_comm_pdaf'] = \ + "Set the MPI communicator used by PDAF.\n\n " \ + "By default, PDAF assumes it can use all available\n " \ + "processes, i.e., `MPI_COMM_WORLD`.\n " \ + "By using this function, we limit the number of processes\n " \ + "that can be used by PDAF to given MPI communicator." + +docstrings['set_offline_mode'] = \ + "Activate offline mode of PDAF." + +docstrings['print_domain_stats'] = \ + "Print screen output of statistics of the local domains\n " \ + "on current process.\n\n " \ + "The statistics include the minimum, maximum, and\n " \ + "average number of local domains per process." + + +docstrings['init_local_obsstats'] = \ + "Initialise the observation statistics of local domain.\n\n " \ + "This function initialise the debug statistics used in\n " \ + ":func:`pyPDAF.PDAF.incr_local_obsstats` and\n " \ + ":func:`pyPDAF.PDAF.print_local_obsstats`.\n\n " \ + "The statistics include:\n " \ + " - number of local domains with observations\n " \ + " - number of local domains without observationss\n " \ + " - maximum local observation dimension\n " \ + " - total observation dimension/total number of domains\n " \ + " - total observation dimension/number of domains with observations" + + +docstrings['incr_local_obsstats'] = \ + "Update observation statistics of local domain.\n\n " \ + "To use this function, one should first initialise\n " \ + "the statistics using :func:`pyPDAF.PDAF.init_local_obsstats`" \ + "\n\n " \ + "The statistics include:\n " \ + " - number of local domains with observations\n " \ + " - number of local domains without observationss\n " \ + " - maximum local observation dimension\n " \ + " - total observation dimension/total number of domains\n " \ + " - total observation dimension/number of domains with observations" + +docstrings['print_local_obsstats'] = \ + "Print screen output of the observation statistics of\n " \ + "local domain.\n\n " \ + "The statistics should be first initialised\n " \ + "by :func:`pyPDAF.PDAF.init_local_obsstats`\n " \ + "and can then be collected by\n " \ + ":func:`pyPDAF.PDAF.incr_local_obsstats`.\n\n " \ + "The statistics include:\n " \ + " - number of local domains with observations\n " \ + " - number of local domains without observationss\n " \ + " - maximum local observation dimension\n " \ + " - total observation dimension/total number of domains\n " \ + " - total observation dimension/number of domains with observations" + +docstrings['omit_obs_omi'] = \ + "Omit observations with large ensemble mean innovation.\n\n " \ + "This function first compute the ensemble mean,\n "\ + "then set large observation error for observations\n " \ + "with large ensemble mean innovation.\n " \ + "This is used in the OMI functionality by\n " \ + "some global filters, e.g. EnKF, LEnKF, PF, NETF.\n " \ + "Therefore, one must first set the related options in OMI.\n " \ + "See `pyPDAF.PDAF.omi_set_xxx` functions and\n " \ + ":func:`pyPDAF.PDAF.omi_gather_obs`." + + +docstrings['omi_init'] = \ + "Allocating an array of `obs_f` derived types instances.\n\n " \ + "This function initialises the number of observation types,\n " \ + "which should be called at the start of the DA system\n " \ + "after :func:`pyPDAF.PDAF.init`." + +docstrings['omi_init_local'] = \ + "Allocating an array of `obs_l` derived types instances.\n\n " \ + "This function initialises the number of observation types\n " \ + "for each local analysis domain,\n " \ + "which should be called at the start of the local analysis loop\n " \ + "in :func:`py__init_dim_obs_l_pdaf`." + +docstrings['omi_set_doassim'] = \ + "Setting the `doassim` attribute of `obs_f`\n " \ + "for `i`-th observation type. This property must be\n " \ + "explicitly set for OMI functionality.\n\n " \ + "Properties of `obs_f` are typically set in user-supplied function\n " \ + "`py__init_dim_obs_pdaf`.\n\n " \ + "This is by default set to 0, which means that\n " \ + "the given type of observation is not assimilated in the DA system." + +docstrings['omi_set_disttype'] = \ + "Setting the observation localisation distance\n " \ + "calculation method\n " \ + "for `i`-th observation type. This is a mandatory property\n " \ + "for OMI functionality.\n\n " \ + "Properties of `obs_f` are typically set in user-supplied function\n " \ + "`py__init_dim_obs_pdaf`.\n\n " \ + "`disttype` determines the way the distance\n " \ + "between observation and model grid is calculated in OMI.\n " \ + "To perform distance computation, the observation coordinates" \ + "should be given by `ocoord_p` argument\n " \ + "when :func:`pyPDAF.PDAF.omi_gather_obs` is called." \ + "\n\n " \ + "See also `PDAF distance computation " \ + "`_." + +docstrings['omi_set_ncoord'] = \ + "Setting the number of spatial dimensions of observations\n " \ + "for `i`-th observation type. This is a mandatory property\n " \ + "for OMI functionality.\n\n " \ + "Properties of `obs_f` are typically set in user-supplied function\n " \ + "`py__init_dim_obs_pdaf`.\n\n " \ + "`ncoord` gives the coordinate dimension of the observation.\n " \ + "This information is used by observation distance computation\n " \ + "for localisation.\n " \ + "For example, `ncoord=2` for 2D observation coordinates." + +docstrings['omi_set_id_obs_p'] = \ + "Setting the `id_obs_p` attribute of `obs_f`\n " \ + "for `i`-th observation type. This is a mandatory property\n " \ + "for OMI functionality.\n\n " \ + "The function is typically used in user-supplied\n " \ + "function `py__init_dim_obs_pdaf`.\n\n " \ + "Here, `id_obs_p(nrows, dim_obs_p)` is a 2D array of integers.\n " \ + "The value of `nrows` depends on the observation operator\n " \ + "used for an observation.\n\n " \ + "Examples:\n\n " \ + "- `nrows=1`: observations are located on model grid point.\n "\ + " In this case,\n " \ + " `id_obs_p` stores the index of the state vector\n " \ + " (starting from 1) corresponds to the observations,\n " \ + " e.g. `id_obs_p[0, j] = i` means that the location\n " \ + " and variable of the `i`-th element of the state vector\n " \ + " is the same as the `j`-th observation.\n\n " \ + "- `nrows=4`: each observation corresponds to\n " \ + " 4 indices of elements in the state vector.\n "\ + " In this case,\n " \ + " the location of these elements is used to perform bi-linear interpolation\n "\ + " from model grid to observation location.\n " \ + " For interpolation, this information is used in the\n "\ + " :func:`pyPDAF.PDAF.omi_obs_op_interp_lin` functions.\n " \ + " This information can also be used to\n " \ + " perform a state vector averaging operator as\n " \ + " observation operator in :func:`pyPDAF.PDAF.omi_obs_op_gridavg`" \ + " When interpolation is needed,\n "\ + " the weighting of the interpolation is done\n "\ + " in the :func:`pyPDAF.PDAF.omi_get_interp_coeff_lin`,\n " \ + " :func:`pyPDAF.PDAF.omi_get_interp_coeff_lin1D`,\n "\ + " and :func:`pyPDAF.PDAF.omi_get_interp_coeff_tri` functions.\n " \ + " The details of interpolation setup can be found at\n " \ + " `PDAF wiki page " \ + "`_.\n" + +docstrings['omi_set_icoeff_p'] = \ + "Setting the observation interpolation coefficient\n " \ + "for `i`-th observation type. This property is optional\n " \ + "unless interpolations needed in observation operators\n " \ + "operator.\n\n " \ + "The function is typically used in user-supplied\n " \ + "function `py__init_dim_obs_pdaf`.\n\n " \ + "`icoeff_p(nrows, dim_obs_p)` is a 2D array of real number\n " \ + "used to interpolate state vector to point-wise observation grid.\n " \ + "The `nrows` is the number of state vector used to interpolate\n " \ + "to one observation location.\n\n " \ + "A suite of functions are provided to obtain these coefficients,\n " \ + "which depend on `obs_f` attribute of `id_obs_p` and\n " \ + "observation coordinates.\n\n " \ + "See also :func:`pyPDAF.PDAF.set_id_obs_p`:\n " \ + " - :func:`pyPDAF.PDAF.omi_get_interp_coeff_lin1D`\n " \ + " 1D interpolation coefficient\n " \ + " - :func:`pyPDAF.PDAF.omi_get_interp_coeff_lin`\n " \ + " linear interpolation coefficient for 1, 2 and 3D rectangular grids\n " \ + " - :func:`pyPDAF.PDAF.omi_get_interp_coeff_tri`\n " \ + " 2D linear interpolation for triangular grids\n\n " \ + "See also `PDAF documentation for OMI interpolations " \ + "`_." + +docstrings['omi_set_domainsize'] = \ + "Setting the domain periodicity\n " \ + "attribute of `obs_f`\n " \ + "for `i`-th observation type. This property is optional\n " \ + "unless localisation is used.\n\n " \ + "The function is typically used in user-supplied\n " \ + "function `py__init_dim_obs_pdaf`.\n\n " \ + "`domainsize(ncoord)` specifies the size of the domain\n " \ + "in each spatial dimension.\n " \ + "This information is used to compute the Cartesian disance\n " \ + "with periodic boundary. That is `disttype = 1 or 11`\n " \ + "Domain size must be positive.\n " \ + "If the value of one dimension is `<=0`,\n " \ + "no periodicity is assumed in that dimension. " + +docstrings['omi_set_obs_err_type'] = \ + "Setting the type of observation error distribution\n " \ + "for `i`-th observation type. This property is optional\n " \ + "unless a laplacian observation error distribution is used.\n\n " \ + "The function is typically used in user-supplied\n " \ + "function `py__init_dim_obs_pdaf`." + +docstrings['omi_set_use_global_obs'] = \ + "Switch for only assimilating process-local observations\n " \ + "for `i`-th observation type.\n\n " \ + "The function is typically used in user-supplied\n " \ + "function `py__init_dim_obs_pdaf`.\n\n " \ + "The filters can be performed in parallel\n " \ + "based on the filtering communicator, `comm_filter`.\n " \ + "This is typically the case for the domain-localised filters,\n " \ + "e.g., LESTK, LETKF, LSEIK, LNETF.\n " \ + "In this case, observation vectors are stored in\n " \ + "process-local vectors, `obs_p`. Each local\n " \ + "process (`obs_p`) only stores a section of the full\n " \ + "observation vector. This typically corresponds to the\n " \ + "local domain corresponding to the filtering process,\n " \ + "based on model domain decomposition.\n\n " \ + "By default, `use_global_obs=1`. This means that\n " \ + "PDAF-OMI assimilates the entire observation vector.\n " \ + "One can choose to only assimilate observations\n " \ + "in local process by setting `use_global_obs=0`.\n " \ + "This can save computational cost used for\n " \ + "observation distance calculations.\n\n " \ + "However, it needs additional preparations to make\n " \ + "PDAF-OMI aware of the limiting coordinates\n " \ + "of a process sub-domain using\n " \ + ":func:`pyPDAF.PDAF.omi_set_domain_limits` or\n " \ + ":func:`pyPDAF.PDAF.omi_set_domain_limits_unstruc`.\n\n\n " \ + "See Also\n " \ + "--------\n " \ + "https://pdaf.awi.de/trac/wiki/OMI_use_global_obs" + +docstrings['omi_set_inno_omit'] = \ + "Setting innovation threshold for removing observation\n " \ + "outliers. By default, no observations are omitted.\n\n " \ + "This function is typically used in user-supplied\n " \ + "function :func:`py__init_dim_obs_pdaf`.\n\n " \ + "The observation omission is only activated when it is > 0.0.\n " \ + "PDAF will omit observations where their squared\n " \ + "the innovation of the ensemble mean is larger than\n " \ + "the product of `inno_omit` and observation error variance.\n\n " \ + "The observations are omitted by setting a very large\n " \ + "observation error variance, i.e., a very small\n " \ + "inverse of the observation error variance, `inno_omit_ivar`.\n " \ + "This can be set by :func:`pyPDAF.PDAF.omi_set_inno_omit_ivar`." + +docstrings['omi_set_inno_omit_ivar'] = \ + "Setting the inverse of observation error variance for\n " \ + "omitted observations.\n\n " \ + "This should be set to a very small value relative to\n " \ + "assimilated observations. By default, it is set to `1e-12`.\n\n " \ + "This function is typically used in user-supplied function\n " \ + ":func:`py__init_dim_obs_pdaf`." + +docstrings['omi_gather_obs'] = \ + "Gather the dimension of a given type of observation across\n " \ + "multiple local domains/filter processors.\n\n " \ + "This function can be used in the user-supplied function of" \ + "\n " \ + ":func:`py__init_dim_obs_f_pdaf`.\n\n " \ + "This function does three things:\n " \ + " 1. Receiving observation dimension on each local process." \ + "\n " \ + " 2. Gather the total dimension of given observation type\n " \ + " across local process and the displacement of PE-local" \ + "\n " \ + " observations relative to the total observation vector" \ + "\n " \ + " 3. Set the observation vector, observation coordinates, " \ + "\n " \ + " the inverse of the observation variance, and localisation" \ + "\n " \ + " radius for this observation type.\n\n " \ + "\n\n " \ + +docstrings['omi_gather_obsstate'] = "This function is used to implement custom observation operators. " \ + "See https://pdaf.awi.de/trac/wiki/OMI_observation_operators#Implementingyourownobservationoperator" +docstrings['omi_set_domain_limits'] = "This is used to set the domain limits for the use of `pyPDAF.PDAF.omi_set_use_global_obs`." \ + "Currently, it only supports 2D limitations. See https://pdaf.awi.de/trac/wiki/PDAFomi_additional_functionality#PDAFomi_set_domain_limit\n " +docstrings['omi_set_debug_flag'] = "This sets the debug flag for OMI. If set to 1, debug information is printed to the screen.\n " \ + "The debug flag can be set to 0 to stop the debugging. See https://pdaf.awi.de/trac/wiki/OMI_debugging" +docstrings['omi_deallocate_obs'] = \ + "Deallocate OMI-internal obsrevation arrays\n\n " \ + "This function should not be called by users\n " \ + "because it is called internally in PDAF." + +docstrings['omi_obs_op_gridpoint'] = \ + "A (partial) identity observation operator\n\n " \ + "This observation operator is used\n " \ + "when observations and model use the same grid. \n\n " \ + "The observations operator selects state vectors\n " \ + "where observations are present based on properties given\n " \ + "in `obs_f`, e.g., `id_obs_p`.\n\n " \ + "The function is used in\n " \ + "the user-supplied function :func:`py__obs_op_pdaf`." + +docstrings['omi_obs_op_gridavg'] = "Observation operator that average values on given model grid points.\n\n " \ + "The averaged model grid points are specified in `id_obs_p` property of `obs_f`,\n " \ + "which can be set in :func:`pyPDAF.PDAF.omi_set_id_obs_p`.\n\n " \ + "The function is used in the user-supplied function `py__obs_op_pdaf`. " +docstrings['omi_obs_op_interp_lin'] = "Observation operator that linearly interpolates model grid values to observation location.\n\n " \ + "The grid points used by linear interpolation is specified in `id_obs_p` of `obs_f`,\n " \ + "which can be set by :func:`pyPDAF.PDAF.omi_set_id_obs_p`.\n\n " \ + "The function also requires `icoeff_p` attribute of `obs_f`,\n " \ + "which can be set by :func:`pyPDAF.PDAF.omi_set_icoeff_p`\n\n " \ + "The interpolation coefficient can be obtained by " \ + ":func:`pyPDAF.PDAF.omi_get_interp_coeff_lin1D`,\n " \ + ":func:`pyPDAF.PDAF.omi_get_interp_coeff_lin`, and\n " \ + ":func:`pyPDAF.PDAF.omi_get_interp_coeff_tri`\n\n " \ + "The details of interpolation setup can be found at\n `PDAF wiki page " \ + "`_\n\n " \ + "The function is used in the user-supplied function `py__obs_op_pdaf`. " +docstrings['omi_obs_op_adj_gridavg'] = "The adjoint observation operator of :func:`pyPDAF.PDAF.omi_obs_op_gridavg`." +docstrings['omi_obs_op_adj_gridpoint'] = "The adjoint observation operator of :func:`pyPDAF.PDAF.omi_obs_op_gridpoint`." +docstrings['omi_obs_op_adj_interp_lin'] = "The adjoint observation operator of :func:`pyPDAF.PDAF.omi_obs_op_interp_lin`." +docstrings['omi_get_interp_coeff_tri'] = "The coefficient for linear interpolation in 2D on unstructure triangular grid.\n\n " \ + "The resulting coefficient is used in :func:`omi_obs_op_interp_lin`.\n\n " \ + "This function is for triangular model grid interpolation coefficients " \ + "determined as barycentric coordinates." +docstrings['omi_get_interp_coeff_lin1D'] = "The coefficient for linear interpolation in 1D.\n\n " \ + "The resulting coefficient is used in :func:`omi_obs_op_interp_lin`.\n\n " +docstrings['omi_get_interp_coeff_lin'] = "The coefficient for linear interpolation up to 3D.\n\n " \ + "The resulting coefficient is used in :func:`omi_obs_op_interp_lin`.\n\n " \ + "See introduction in `PDAF-OMI wiki page \n " \ + "`_" + + +docstrings['omi_init_obs_f_cb'] = "This function is an internal PDAF-OMI function that is used as a call-back function to initialise the observation vector. " \ + "This could be used to modify the observation vector when OMI is used with `pyPDAF.PDAF.assimilate_xxx` instead of `pyPDAF.PDAF.omi_assimilate_xxx`." +docstrings['omi_init_obsvar_cb'] = "This function is an internal PDAF function that is used as a call-back function to initialise the observation error variance. " \ + "This could be used to modify the observation variance when OMI is used with `pyPDAF.PDAF.assimilate_xxx` instead of `pyPDAF.PDAF.omi_assimilate_xxx`." +docstrings['omi_g2l_obs_cb'] = "This function is an internal PDAF-OMI function that is used as a call-back function to convert between global and local observation vectors in domain localisation.\n " +docstrings['omi_init_obs_l_cb'] = "This function is an internal PDAF-OMI function that is used as a call-back function to initialise local observation vector in domain localisation. " \ + "This could be used to modify the observation variance when OMI is used with `pyPDAF.PDAF.assimilate_xxx` instead of `pyPDAF.PDAF.omi_assimilate_xxx`." +docstrings['omi_init_obsvar_l_cb'] = "This function is an internal PDAF-OMI function that is used as a call-back function to initialise local observation vector in domain localisation. " \ + "This could be used to modify the observation variance when OMI is used with `pyPDAF.PDAF.assimilate_xxx` instead of `pyPDAF.PDAF.omi_assimilate_xxx`." +docstrings['omi_prodRinvA_l_cb'] = "This function is an internal PDAF-OMI function that is used as a call-back function to perform the matrix multiplication inverse of local observation error covariance and a matrix A in domain localisation. " \ + "This could be used to modify the observation variance when OMI is used with `pyPDAF.PDAF.assimilate_xxx` instead of `pyPDAF.PDAF.omi_assimilate_xxx`." +docstrings['omi_likelihood_l_cb'] = "This is an internal PDAF-OMI function that is used as a call-back function to compute the likelihood of the observation for a given ensemble member according to the observations used for the local analysis in the localized LNETF. " \ + "This could be used to modify the observation variance when OMI is used with `pyPDAF.PDAF.assimilate_xxx` instead of `pyPDAF.PDAF.omi_assimilate_xxx`. See https://pdaf.awi.de/trac/wiki/U_likelihood_l" +docstrings['omi_prodRinvA_cb'] = "This function is an internal PDAF-OMI function that is used as a call-back function to perform the matrix multiplication inverse of observation errro covariance and a matrix A. " \ + "This could be used to modify the observation variance when OMI is used with `pyPDAF.PDAF.assimilate_xxx` instead of `pyPDAF.PDAF.omi_assimilate_xxx`." +docstrings['omi_likelihood_cb'] = "This is an internal PDAF-OMI function that is used as a call-back function to compute the likelihood of the observation for a given ensemble member according to the observations used for the local analysis for NETF or particle filter. " \ + "This could be used to modify the observation variance when OMI is used with `pyPDAF.PDAF.assimilate_xxx` instead of `pyPDAF.PDAF.omi_assimilate_xxx`. See https://pdaf.awi.de/trac/wiki/U_likelihood_l" +docstrings['omi_add_obs_error_cb'] = "This is an internal PDAF-OMI function that is used as a call-back function to add random observation error to stochastic EnKF. " \ + "This could be used to modify the observation variance when OMI is used with `pyPDAF.PDAF.assimilate_xxx` instead of `pyPDAF.PDAF.omi_assimilate_xxx`. See https://pdaf.awi.de/trac/wiki/U_likelihood_l" +docstrings['omi_init_obscovar_cb'] = "This is an internal PDAF-OMI function that is used as a call-back function to construct a full observation error covariance matrix used only in stochastic EnKF. " \ + "This could be used to modify the observation variance when OMI is used with `pyPDAF.PDAF.assimilate_xxx` instead of `pyPDAF.PDAF.omi_assimilate_xxx`." +docstrings['omi_init_obserr_f_cb'] = "This is an internal PDAF-OMI function that is used as a call-back function to construct a full observation error covariance matrix used only in stochastic EnKF. " \ + "This could be used to modify the observation variance when OMI is used with `pyPDAF.PDAF.assimilate_xxx` instead of `pyPDAF.PDAF.omi_assimilate_xxx`." +docstrings['omi_prodRinvA_hyb_l_cb'] = "This function is an internal PDAF-OMI function that is used as a call-back function to perform the matrix multiplication inverse of local observation error covariance and a matrix A in LKNETF. " \ + "This could be used to modify the observation variance when OMI is used with `pyPDAF.PDAF.assimilate_xxx` instead of `pyPDAF.PDAF.omi_assimilate_xxx`." +docstrings['omi_likelihood_hyb_l_cb'] = "This is an internal PDAF-OMI function that is used as a call-back function to compute the likelihood of the observation for a given ensemble member according to the observations used for the local analysis in LKNETF. " \ + "This could be used to modify the observation variance when OMI is used with `pyPDAF.PDAF.assimilate_xxx` instead of `pyPDAF.PDAF.omi_assimilate_xxx`. See https://pdaf.awi.de/trac/wiki/U_likelihood_l" + +docstrings['omi_obsstats_l'] = "This function is called in the update routine of local filters and write statistics on locally used and excluded observations." +docstrings['omi_weights_l'] = "This function computes a weight vector according to the distances of observations from the local analysis domain with a vector of localisation radius." +docstrings['omi_weights_l_sgnl'] = "This function computes a weight vector according to the distances of observations from the local analysis domain with given localisation radius." +docstrings['omi_check_error'] = "This function returns the value of the PDAF-OMI internal error flag." +docstrings['omi_gather_obsdims'] = "This function gathers the information about the full dimension of each observation type in each process-local subdomain." +docstrings['omi_obsstats'] = "The function is called in the update routine of global filters and writes statistics on used and excluded observations." +docstrings['omi_init_dim_obs_l_iso'] = "The function has to be called in `init_dim_obs_l_OBTYPE` in each observation module if a domain-localized filter (LESTKF/LETKF/LNETF/LSEIK)is used. " \ + "It initialises the local observation information for PDAF-OMI for a single local analysis domain. This is used for isotropic localisation " \ + "where the localisation radius is the same in all directions." +docstrings['omi_init_dim_obs_l_noniso'] = "The function has to be called in `init_dim_obs_l_OBTYPE` in each observation module if a domain-localized filter (LESTKF/LETKF/LNETF/LSEIK)is used. " \ + "It initialises the local observation information for PDAF-OMI for a single local analysis domain. This is used for non-isotropic localisation " \ + "where the localisation radius is different in each direction. See https://pdaf.awi.de/trac/wiki/OMI_observation_modules#init_dim_obs_l_OBSTYPE and https://pdaf.awi.de/trac/wiki/PDAFomi_init_dim_obs_l#Settingsfornon-isotropiclocalization." +docstrings['omi_init_dim_obs_l_noniso_locweights'] = "The function has to be called in `init_dim_obs_l_OBTYPE` in each observation module if a domain-localized filter (LESTKF/LETKF/LNETF/LSEIK)is used. " \ + "It initialises the local observation information for PDAF-OMI for a single local analysis domain. This is used for non-isotropic localisation and different weight functions for horizontal and vertical directions. " \ + "See https://pdaf.awi.de/trac/wiki/OMI_observation_modules#init_dim_obs_l_OBSTYPE and https://pdaf.awi.de/trac/wiki/PDAFomi_init_dim_obs_l#Settingdifferentweightfunctsforhorizontalandverticaldirections." +docstrings['omi_localize_covar_iso'] = "The function has to be called in `localize_covar_OBTYPE` in each observation module. It applies the covariance localisation in stochastic EnKF. This is used for isotropic localisation " \ + "where the localisation radius is the same in all directions. See https://pdaf.awi.de/trac/wiki/PDAFomi_localize_covar" +docstrings['omi_localize_covar_noniso'] = "The function has to be called in `localize_covar_OBTYPE` in each observation module. It applies the covariance localisation in stochastic EnKF. This is used for non-isotropic localisation " \ + "where the localisation radius is different. See https://pdaf.awi.de/trac/wiki/PDAFomi_localize_covar" +docstrings['omi_localize_covar_noniso_locweights'] = "The function has to be called in `localize_covar_OBTYPE` in each observation module. It applies the covariance localisation in stochastic EnKF. This is used for non-isotropic localisation with different weight function for horizontal and vertical directions. " \ + "where the localisation radius is different. See https://pdaf.awi.de/trac/wiki/PDAFomi_localize_covar" + +docstrings['omi_omit_by_inno_l_cb'] = "The function is called during the analysis step on each local analysis domain. " \ + "It checks the size of the innovation and sets the observation error to a high value " \ + "if the squared innovation exceeds a limit relative to the observation error variance." \ + "This function is an internal PDAF-OMI function that is used as a call-back function. " \ + "This could be used to modify the observation vector when OMI is used with `pyPDAF.PDAF.assimilate_xxx` instead of `pyPDAF.PDAF.omi_assimilate_xxx`." + +docstrings['omi_omit_by_inno_cb'] = "The function is called during the analysis step of a global filter. " \ + "It checks the size of the innovation and " \ + "sets the observation error to a high value " \ + "if the squared innovation exceeds a limit relative to the observation error variance.""This function is called in the update routine of local filters and write statistics on locally used and excluded observations." \ + "This function is an internal PDAF-OMI function that is used as a call-back function. " \ + "This could be used to modify the observation vector when OMI is used with `pyPDAF.PDAF.assimilate_xxx` instead of `pyPDAF.PDAF.omi_assimilate_xxx`." + +docstrings['omi_set_localization'] = "This function sets localization information " \ + "(locweight, cradius, sradius) in OMI, " \ + "and allocates local arrays for cradius and sradius, i.e. `obs_l`. " \ + "This variant is for isotropic localization. " \ + "The function is used by user-supplied implementations of " \ + "`pyPDAF.PDAF.omi_init_dim_obs_l_iso`. " +docstrings['omi_set_localization_noniso'] = "This function sets localization information " \ + "(locweight, cradius, sradius) in OMI, " \ + "and allocates local arrays for cradius and sradius, i.e. `obs_l`. " \ + "This variant is for non-isotropic localization. " \ + "The function is used by user-supplied implementations of " \ + "`pyPDAF.PDAF.omi_init_dim_obs_l_noniso`. " +docstrings['omi_set_dim_obs_l'] = "This function initialises number local observations. " \ + "It also returns number of local observations up to the current observation type. " \ + "It is used by a user-supplied implementations of " \ + "`pyPDAF.PDAF.omi_init_dim_obs_l_xxx`." +docstrings['omi_store_obs_l_index'] = "This function stores the mapping index " \ + "between the global and local observation vectors, " \ + "the distance and the cradius and sradius " \ + "for a single observations in OMI. " \ + "This variant is for non-factorised localisation. " \ + "The function is used by user-supplied implementations of " \ + "`pyPDAF.PDAF.omi_init_dim_obs_l_iso` or `pyPDAF.PDAF.omi_init_dim_obs_l_noniso`. " +docstrings['omi_store_obs_l_index_vdist'] = "This function stores the mapping index " \ + "between the global and local observation vectors, " \ + "the distance and the cradius and sradius " \ + "for a single observations in OMI. " \ + "This variant is for 2D+1D factorised localisation.\n " \ + "The function is used by user-supplied implementations of " \ + "`pyPDAF.PDAF.omi_init_dim_obs_l_noniso_locweights`." + + +docstrings['local_set_indices'] = "Set index vector to map local state vector to global state vectors. " \ + "This is called in the user-supplied function `py__init_dim_l_pdaf`." +docstrings['local_set_increment_weights'] = "This function initialises a PDAF_internal local array " \ + "of increment weights. The weights are applied in " \ + "in PDAF_local_l2g_cb where the local state vector\n " \ + "is weighted by given weights. " \ + "These can e.g. be used to apply a vertical localisation." +docstrings['local_clear_increment_weights'] = "This function deallocates the local increment weight vector " \ + "in `pyPDAF.PDAF.local_set_increment_weights` if it is allocated" +docstrings['local_g2l_cb'] = "Project a global to a local state vector for the localized filters.\n " \ + "This is the full callback function to be used internally. The mapping " \ + "is done using the index vector id_lstate_in_pstate that is initialised " \ + "in `pyPDAF.PDAF.local_set_indices`." +docstrings['local_l2g_cb'] = "Initialise elements of a global state vector from a local state vector.\n " \ + "This is the full callback function to be used internally. The mapping " \ + "is done using the index vector `id_lstate_in_pstate` that is initialised " \ + "in `pyPDAF.PDAF.local_set_indices`. \n \n " \ + "To exclude any element of the local state vector from the initialisation" \ + "one can set the corresponding index value to 0." diff --git a/pyPDAF/source/tool/docstring/pdaf_assimilate_docstrings.py b/pyPDAF/source/tool/docstring/pdaf_assimilate_docstrings.py new file mode 100644 index 0000000000000000000000000000000000000000..f754d5885d04a0c2c83f3a869753d2be5fc3cd9f --- /dev/null +++ b/pyPDAF/source/tool/docstring/pdaf_assimilate_docstrings.py @@ -0,0 +1,978 @@ +"""docstrings for PDAF_assimilate functions + +These functions are mostly deprecated. +""" +docstrings = dict() + + +docstrings['assimilate_3dvar'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_3dvar`\n "\ + "or :func:`pyPDAF.PDAF.omi_assimilate_3dvar_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "3DVar DA for a single step without OMI.\n " \ + "When 3DVar is used, the background error covariance matrix"\ + "\n has to be modelled for cotrol variable\n " \ + "transformation. This is a deterministic filtering\n " \ + "scheme so no ensemble and\n " \ + "parallelisation is needed.\n " \ + "This function should be called at each model time step.\n" \ + "\n The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.put_state_3dvar`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n "\ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. Iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__prodRinvA_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_pdaf\n " \ + " 6. core DA algorithm\n " \ + " 7. py__cvt_pdaf\n " \ + " 8. py__prepoststep_state_pdaf\n " \ + " 9. py__distribute_state_pdaf\n " \ + " 10. py__next_observation_pdaf\n\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by :func:`pyPDAF.PDAF.omi_assimilate_3dvar`\n " \ + " and :func:`pyPDAF.PDAF.omi_assimilate_3dvar_nondiagR`" +docstrings['assimilate_en3dvar_estkf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_en3dvar_estkf`\n "\ + "or :func:`pyPDAF.PDAF.omi_assimilate_en3dvar_estkf_nondiagR`." \ + "\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "3DEnVar for a single DA step.\n " \ + "The background error covariance matrix is estimated\n " \ + "by an ensemble.\n " \ + "The 3DEnVar only calculates the analysis of the ensemble mean." \ + "\n " \ + "An ESTKF is used along with 3DEnVar\n " \ + "to generate ensemble perturbations.\n " \ + "This function should be called at each model time step.\n" \ + "\n The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.put_state_en3dvar_estkf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. the iterative optimisation:\n " \ + " 1. py__cvt_ens_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__prodRinvA_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_ens_pdaf\n " \ + " 6. core 3DEnVar algorithm\n " \ + " 7. py__cvt_ens_pdaf\n " \ + " 8. ESTKF:\n " \ + " 1. py__init_dim_obs_pdaf\n " \ + " 2. py__obs_op_pdaf (for ensemble mean)\n " \ + " 3. py__init_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for each ensemble member)\n " \ + " 5. py__init_obsvar_pdaf\n " \ + " (only relevant for adaptive\n " \ + " forgetting factor schemes)\n " \ + " 6. py__prodRinvA_pdaf\n " \ + " 7. core ESTKF algorithm\n " \ + " 9. py__prepoststep_state_pdaf\n " \ + " 10. py__distribute_state_pdaf\n " \ + " 11. py__next_observation_pdaf\n\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.omi_assimilate_en3dvar_estkf`\n " \ + " and :func:`pyPDAF.PDAF.omi_assimilate_en3dvar_estkf_nondiagR`" +docstrings['assimilate_en3dvar_lestkf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf` or" \ + "\n " \ + ":func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf_nondiagR`."\ + "\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "3DEnVar for a single DA step where the ensemble anomaly\n " \ + "is generated by LESTKF.\n " \ + "The background error covariance matrix is\n " \ + "estimated by ensemble.\n " \ + "The 3DEnVar only calculates the analysis of the ensemble mean." \ + "\n " \ + "An LESTKF is used to generate ensemble perturbations.\n " \ + "This function should be called at each model time step.\n" \ + "\n " \ + "The function is a combination of" \ + "\n " \ + ":func:`pyPDAF.PDAF.put_state_en3dvar_lestkf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. Starting the iterative optimisation:\n " \ + " 1. py__cvt_ens_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__prodRinvA_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_ens_pdaf\n " \ + " 6. core DA algorithm\n " \ + " 7. py__cvt_ens_pdaf\n " \ + " 8. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n "\ + " (for each ensemble member)\n " \ + " 4. py__init_obs_pdaf\n "\ + " (if global adaptive forgetting factor is used\n " \ + " `type_forget=1` in :func:`pyPDAF.PDAF.init`)\n " \ + " 5. py__init_obsvar_pdaf\n "\ + " (if global adaptive forgetting factor is used)" \ + "\n " \ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_state_pdaf\n " \ + " 4. py__g2l_obs_pdaf\n "\ + " (localise mean ensemble in observation space)"\ + "\n " \ + " 5. py__init_obs_l_pdaf\n "\ + " 6. py__g2l_obs_pdaf\n " \ + " (localise each ensemble member\n " \ + " in observation space)\n " \ + " 7. py__init_obsvar_l_pdaf\n " \ + " (only called if local\n " \ + " adaptive forgetting factor\n " \ + " `type_forget=2` is used)\n "\ + " 8. py__prodRinvA_l_pdaf\n " \ + " 9. core DA algorithm\n " \ + " 10. py__l2g_state_pdaf\n " \ + " 9. py__prepoststep_state_pdaf\n " \ + " 10. py__distribute_state_pdaf\n " \ + " 11. py__next_observation_pdaf\n\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf`" \ + "\n " \ + " and\n " \ + " :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf_nondiagR`" +docstrings['assimilate_hyb3dvar_estkf'] = \ + "It is recommended to use" \ + "\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_hyb3dvar_estkf`\n "\ + "or :func:`pyPDAF.PDAF.omi_assimilate_hyb3dvar_estkf_nondiagR`." \ + "\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions" \ + "\n " \ + "and improved efficiency.\n\n " \ + "Hybrid 3DEnVar for a single DA step where\n " \ + "the background error covariance is hybridised by" \ + "\n " \ + "a static background error covariance,\n " \ + "and a flow-dependent background error covariance" \ + "\n " \ + "estimated from ensemble.\n " \ + "The 3DVar generates an ensemble mean and" \ + "\n " \ + "the ensemble perturbation is generated by\n " \ + "ESTKF in this implementation.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of" \ + "\n " \ + ":func:`pyPDAF.PDAF.put_state_hyb3dvar_estkf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. the iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__cvt_ens_pdaf\n " \ + " 3. py__obs_op_lin_pdaf\n " \ + " 4. py__prodRinvA_pdaf\n " \ + " 5. py__obs_op_adj_pdaf\n " \ + " 6. py__cvt_adj_pdaf\n " \ + " 7. py__cvt_adj_ens_pdaf\n " \ + " 8. core 3DEnVar algorithm\n " \ + " 7. py__cvt_pdaf\n " \ + " 8. py__cvt_ens_pdaf\n " \ + " 9. Perform ESTKF:\n " \ + " 1. py__init_dim_obs_pdaf\n " \ + " 2. py__obs_op_pdaf\n "\ + " (for ensemble mean)\n " \ + " 3. py__init_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " (for each ensemble member)\n " \ + " 5. py__init_obsvar_pdaf\n " \ + " (only relevant for adaptive" \ + "\n " \ + " forgetting factor schemes)\n " \ + " 6. py__prodRinvA_pdaf\n " \ + " 7. core ESTKF algorithm\n " \ + " 10. py__prepoststep_state_pdaf\n " \ + " 11. py__distribute_state_pdaf\n " \ + " 12. py__next_observation_pdaf\n\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by" \ + "\n " \ + " :func:`pyPDAF.PDAF.omi_assimilate_hyb3dvar_estkf` and" \ + "\n " \ + " :func:`pyPDAF.PDAF.omi_assimilate_hyb3dvar_estkf_nondiagR`." +docstrings['assimilate_hyb3dvar_lestkf'] = \ + "It is recommended to use" \ + "\n " \ + ":func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf` or" \ + "\n "\ + ":func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf_nondiagR`." \ + "\n\n " \ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "Hybrid 3DEnVar for a single DA step where\n " \ + "the background error covariance is hybridised by\n " \ + "a static background error covariance,\n " \ + "and a flow-dependent background error covariance\n " \ + "estimated from ensemble.\n " \ + "The 3DVar generates an ensemble mean and\n " \ + "the ensemble perturbation is generated by\n " \ + "LESTKF in this implementation.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.put_state_hyb3dvar_lestkf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. The iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__cvt_ens_pdaf\n " \ + " 3. py__obs_op_lin_pdaf\n " \ + " 4. py__prodRinvA_pdaf\n " \ + " 5. py__obs_op_adj_pdaf\n " \ + " 6. py__cvt_adj_pdaf\n " \ + " 7. py__cvt_adj_ens_pdaf\n " \ + " 8. core DA algorithm\n " \ + " 7. py__cvt_pdaf\n " \ + " 8. py__cvt_ens_pdaf\n " \ + " 9. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n " \ + " (for each ensemble member)\n " \ + " 4. py__init_obs_pdaf\n " \ + " (if global adaptive forgetting factor\n " \ + " `type_forget=1` in :func:`pyPDAF.PDAF.init`)\n " \ + " 5. py__init_obsvar_pdaf\n " \ + " (if global adaptive forgetting factor is used)\n " \ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_state_pdaf\n " \ + " 4. py__g2l_obs_pdaf\n "\ + " (localise mean ensemble in observation space)" \ + "\n " \ + " 5. py__init_obs_l_pdaf\n "\ + " 6. py__g2l_obs_pdaf\n " \ + " (localise each ensemble member\n " \ + " in observation space)\n " \ + " 7. py__init_obsvar_l_pdaf\n " \ + " (only called if local adaptive forgetting\n " \ + " factor `type_forget=2` is used)\n "\ + " 8. py__prodRinvA_l_pdaf\n " \ + " 9. core DA algorithm\n " \ + " 10. py__l2g_state_pdaf\n " \ + " 10. py__prepoststep_state_pdaf\n " \ + " 11. py__distribute_state_pdaf\n " \ + " 12. py__next_observation_pdaf\n\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf`" \ + "\n " \ + " and\n " \ + " :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf_nondiagR`" +docstrings['assimilate_enkf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_global`\n "\ + "or :func:`pyPDAF.PDAF.omi_assimilate_enkf_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "Stochastic EnKF (ensemble " \ + "Kalman filter) [1]_ for a single DA step without OMI.\n " \ + "This function should be called at each model time step. \n\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.put_state_enkf` " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for ensemble mean)\n " \ + " 5. py__add_obs_err_pdaf\n " \ + " 6. py__init_obs_pdaf\n " \ + " 7. py__init_obscovar_pdaf\n " \ + " 8. py__obs_op_pdaf (for each ensemble member)\n " \ + " 9. core DA algorithm\n " \ + " 10. py__prepoststep_state_pdaf\n " \ + " 11. py__distribute_state_pdaf\n " \ + " 12. py__next_observation_pdaf\n\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.omi_assimilate_global`\n " \ + " and :func:`pyPDAF.PDAF.omi_assimilate_enkf_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Evensen, G. (1994), \n "\ + " Sequential data assimilation with a nonlinear\n " \ + " quasi-geostrophic model\n "\ + " using Monte Carlo methods to forecast error statistics," \ + "\n "\ + " J. Geophys. Res., 99(C5), 10143–10162,\n " \ + " doi:10.1029/94JC00572." +docstrings['assimilate_estkf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_global`\n " \ + "or :func:`pyPDAF.PDAF.omi_assimilate_global_nondiagR`\n " \ + "instead of this function.\n\n " \ + "OMI functions need fewer user-supplied functions\n " \ + "and improve DA efficiency.\n\n " \ + "This function calls ESTKF\n " \ + "(error space transform Kalman filter) [1]_.\n " \ + "The ESTKF is a more efficient equivalent to the ETKF.\n\n " \ + "The function should be called at each model time step.\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.put_state_estkf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for ensemble mean)\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. py__obs_op_pdaf (for each ensemble member)\n " \ + " 7. py__init_obsvar_pdaf (only relevant\n " \ + " for adaptive forgetting factor schemes)\n " \ + " 8. py__prodRinvA_pdaf\n " \ + " 9. core DA algorithm\n " \ + " 10. py__prepoststep_state_pdaf\n " \ + " 11. py__distribute_state_pdaf\n " \ + " 12. py__next_observation_pdaf\n\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.omi_assimilate_global`\n " \ + " and :func:`pyPDAF.PDAF.omi_assimilate_global_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012)."\ + "\n " \ + " A unification of ensemble square root Kalman filters." \ + "\n " \ + " Monthly Weather Review, 140, 2335-2345.\n " \ + " doi:10.1175/MWR-D-11-00102.1" +docstrings['assimilate_etkf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_global`\n "\ + "or :func:`pyPDAF.PDAF.omi_assimilate_global_nondiagR`.\n\n "\ + "PDAFlocal-OMI modules require fewer\n " \ + "user-supplied functions and improved efficiency.\n\n " \ + "Using ETKF (ensemble transform\n " \ + "Kalman filter) [1]_ for a single DA step without OMI.\n " \ + "The implementation is baed on [2]_.\n\n " \ + "This function should be called at each model time step.\n " \ + "The function is a combination of \n " \ + ":func:`pyPDAF.PDAF.put_state_etkf` " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for ensemble mean)\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. py__obs_op_pdaf (for each ensemble member)\n " \ + " 7. py__init_obsvar_pdaf (only relevant for\n " \ + " adaptive forgetting factor schemes)\n " \ + " 8. py__prodRinvA_pdaf\n " \ + " 9. core DA algorithm\n " \ + " 10. py__prepoststep_state_pdaf\n " \ + " 11. py__distribute_state_pdaf\n " \ + " 12. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.omi_assimilate_global`\n " \ + " and :func:`pyPDAF.PDAF.omi_assimilate_global_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Bishop, C. H., B. J. Etherton, and S. J. Majumdar (2001)" \ + "\n "\ + " Adaptive Sampling with the Ensemble\n " \ + " Transform Kalman Filter.\n " \ + " Part I: Theoretical Aspects. Mon. Wea. Rev.,\n " \ + " 129, 420–436,\n "\ + " doi: 10.1175/1520-0493(2001)129<0420:ASWTET>2.0.CO;2." \ + "\n " \ + ".. [2] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012)." \ + "\n " \ + " A unification of ensemble square root Kalman filters." \ + "\n " \ + " Monthly Weather Review, 140, 2335-2345.\n " \ + " doi:10.1175/MWR-D-11-00102.1" +docstrings['assimilate_seek'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_global`\n "\ + "or :func:`pyPDAF.PDAF.omi_assimilate_global_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "This function will use singular evolutive\n " \ + "extended Kalman filter [1]_ for a single DA step.\n " \ + "This is a deterministic Kalman filter.\n " \ + "The function should be called at each model step.\n\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.put_state_seek`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n "\ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for ensemble mean)\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. py__obs_op_pdaf (for each ensemble member)\n " \ + " 7. py__prodRinvA_pdaf\n " \ + " 8. core DA algorithm\n " \ + " 9. py__prepoststep_state_pdaf\n " \ + " 10. py__distribute_state_pdaf\n " \ + " 11. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.omi_assimilate_global`\n " \ + " and :func:`pyPDAF.PDAF.omi_assimilate_global_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Pham, D. T., Verron, J., & Roubaud, M. C. (1998).\n "\ + " A singular evolutive extended Kalman filter\n " \ + " for data assimilation\n "\ + " in oceanography. Journal of Marine systems,\n " \ + " 16(3-4), 323-340." +docstrings['assimilate_seik'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_global`\n "\ + "or :func:`pyPDAF.PDAF.omi_assimilate_global_nondiagR`.\n\n " \ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "This function will use singular evolutive\n " \ + "interpolated Kalman filter [1]_ for a single DA step.\n " \ + "The function should be called at each model step.\n\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.put_state_seik`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n "\ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for ensemble mean)\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. py__obs_op_pdaf (for each ensemble member)\n " \ + " 7. py__init_obsvar_pdaf (only relevant for\n " \ + " adaptive forgetting factor schemes)\n " \ + " 8. py__prodRinvA_pdaf\n " \ + " 9. core DA algorithm\n " \ + " 10. py__prepoststep_state_pdaf\n " \ + " 11. py__distribute_state_pdaf\n " \ + " 12. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.omi_assimilate_global`\n " \ + " and :func:`pyPDAF.PDAF.omi_assimilate_global_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Pham, D. T., Verron, J., & Roubaud, M. C. (1998).\n "\ + " A singular evolutive extended Kalman\n " \ + " filter for data assimilation\n "\ + " in oceanography. Journal of Marine systems,\n " \ + " 16(3-4), 323-340." +docstrings['assimilate_netf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_global`\n "\ + "or :func:`pyPDAF.PDAF.omi_assimilate_nonlin_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "This function will use Nonlinear Ensemble\n " \ + "Transform Filter (NETF) [1]_ \n " \ + "for a single DA step. The nonlinear filter\n " \ + "computes the distribution up to\n " \ + "the second moment similar to KF but using\n " \ + "a nonlinear weighting similar to\n " \ + "particle filter. This leads to an equal\n " \ + "weights assumption for prior ensemble.\n " \ + "The function should be called at each model step.\n\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.put_state_netf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n "\ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__init_obs_pdaf\n " \ + " 5. py__obs_op_pdaf (for each ensemble member)\n " \ + " 6. py__likelihood_pdaf\n " \ + " 7. core DA algorithm\n " \ + " 8. py__prepoststep_state_pdaf\n " \ + " 9. py__distribute_state_pdaf\n " \ + " 10. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.omi_assimilate_global`\n " \ + " and :func:`pyPDAF.PDAF.omi_assimilate_nonlin_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Tödter, J., and B. Ahrens, 2015:\n "\ + " A second-order exact ensemble square root filter\n " \ + " for nonlinear data assimilation. Mon. Wea. Rev.,\n " \ + " 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1." +docstrings['assimilate_pf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_global`\n "\ + "or :func:`pyPDAF.PDAF.omi_assimilate_nonlin_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "This function will use particle filter for a single DA step." \ + "\n " \ + "This is a fully nonlinear filter, and may require\n " \ + "a high number of ensemble members.\n " \ + "A review of particle filter can be found at [1]_.\n " \ + "The function should be called at each model step.\n\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.put_state_pf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n "\ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__init_obs_pdaf\n " \ + " 5. py__obs_op_pdaf (for each ensemble member)\n " \ + " 6. py__likelihood_pdaf\n " \ + " 7. core DA algorithm\n " \ + " 8. py__prepoststep_state_pdaf\n " \ + " 9. py__distribute_state_pdaf\n " \ + " 10. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.omi_assimilate_global`\n " \ + " and :func:`pyPDAF.PDAF.omi_assimilate_nonlin_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Van Leeuwen, P. J., Künsch, H. R.,\n " \ + " Nerger, L., Potthast, R., & Reich, S. (2019).\n "\ + " Particle filters for high‐dimensional geoscience\n " \ + " applications:\n "\ + " A review. Quarterly Journal of the Royal\n " \ + " Meteorological Society, 145(723), 2335-2365." +docstrings['assimilate_lenkf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_lenkf`\n "\ + "or :func:`pyPDAF.PDAF.omi_assimilate_lenkf_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "Stochastic EnKF (ensemble Kalman filter)\n " \ + "with covariance localisation [1]_\n " \ + "for a single DA step without OMI.\n\n " \ + "This is the only scheme for covariance localisation in PDAF." \ + "\n\n " \ + "This function should be called at each model time step.\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.put_state_lenkf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for each ensemble member)\n " \ + " 5. py__localize_pdaf\n " \ + " 6. py__add_obs_err_pdaf\n " \ + " 7. py__init_obs_pdaf\n " \ + " 8. py__init_obscovar_pdaf\n " \ + " 9. py__obs_op_pdaf (repeated to reduce storage)\n " \ + " 10. core DA algorith\n " \ + " 11. py__prepoststep_state_pdaf\n " \ + " 12. py__distribute_state_pdaf\n " \ + " 13. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.omi_assimilate_lenkf`\n " \ + " and :func:`pyPDAF.PDAF.omi_assimilate_lenkf_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Houtekamer, P. L., and H. L. Mitchell (1998): \n " \ + " Data Assimilation Using an Ensemble Kalman Filter\n " \ + " Technique.\n "\ + " Mon. Wea. Rev., 126, 796–811,\n "\ + " doi: 10.1175/1520-0493(1998)126<0796:DAUAEK>2.0.CO;2." +docstrings['assimilate_lestkf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.localomi_assimilate`\n "\ + "or :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`.\n\n "\ + "PDAFlocal-OMI modules require fewer user-supplied\n " \ + "functions and improved efficiency.\n\n " \ + "Local ESTKF (error space transform " \ + "Kalman filter) [1]_ for a single DA step without OMI.\n " \ + "The LESTKF is a more efficient equivalent to the LETKF.\n\n " \ + "This function should be called at each model time step.\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.put_state_lestkf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. py__init_obs_pdaf\n " \ + " (if global adaptive forgetting factor\n " \ + " `type_forget=1` is used\n " \ + " in :func:`pyPDAF.PDAF.init`)\n "\ + " 7. py__init_obsvar_pdaf (if global adaptive\n " \ + " forgetting factor is used)\n "\ + " 8. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__g2l_state_pdaf\n "\ + " 4. py__g2l_obs_pdaf (localise mean ensemble\n " \ + " in observation space)\n "\ + " 5. py__init_obs_l_pdaf\n " \ + " 6. py__g2l_obs_pdaf\n "\ + " (localise each ensemble member\n " \ + " in observation space)\n "\ + " 7. py__init_obsvar_l_pdaf\n " \ + " (only called if local adaptive\n " \ + " forgetting factor `type_forget=2` is used)\n " \ + " 8. py__prodRinvA_l_pdaf\n "\ + " 9. core DA algorithm\n " \ + " 10. py__l2g_state_pdaf\n "\ + " 9. py__prepoststep_state_pdaf\n "\ + " 10. py__distribute_state_pdaf\n "\ + " 11. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.localomi_assimilate`\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012)." \ + "\n " \ + " A unification of ensemble square root Kalman filters." \ + "\n " \ + " Monthly Weather Review, 140, 2335-2345.\n " \ + " doi:10.1175/MWR-D-11-00102.1" +docstrings['assimilate_letkf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.localomi_assimilate`\n "\ + "or :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`.\n\n "\ + "PDAFlocal-OMI modules require fewer user-supplied\n " \ + "functions and improved efficiency.\n\n " \ + "Local ensemble transform Kalman filter (LETKF) [1]_ " \ + "for a single DA step without OMI.\n " \ + "Implementation is based on [2]_.\n " \ + "Note that the LESTKF is a more efficient equivalent\n " \ + "to the LETKF.\n\n " \ + "This function should be called at each model time step.\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.put_state_letkf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. py__init_obs_pdaf\n " \ + " (if global adaptive forgetting factor\n " \ + " `type_forget=1` is used\n " \ + " in :func:`pyPDAF.PDAF.init`)\n "\ + " 7. py__init_obsvar_pdaf (if global adaptive\n " \ + " forgetting factor is used)\n "\ + " 8. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__g2l_state_pdaf\n "\ + " 4. py__g2l_obs_pdaf (localise mean ensemble\n " \ + " in observation space)\n "\ + " 5. py__init_obs_l_pdaf\n " \ + " 6. py__g2l_obs_pdaf (localise each ensemble member" \ + "\n " \ + " in observation space)\n "\ + " 7. py__init_obsvar_l_pdaf\n " \ + " (only called if local adaptive forgetting factor" \ + "\n " \ + " `type_forget=2` is used)\n " \ + " 8. py__prodRinvA_l_pdaf\n "\ + " 9. core DA algorithm\n " \ + " 10. py__l2g_state_pdaf\n "\ + " 9. py__prepoststep_state_pdaf\n "\ + " 10. py__distribute_state_pdaf\n "\ + " 11. py__next_observation_pdaf\n\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.localomi_assimilate`\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Hunt, B. R., Kostelich, E. J., & Szunyogh, I. (2007)." \ + "\n "\ + " Efficient data assimilation for spatiotemporal chaos:" \ + "\n "\ + " A local ensemble transform Kalman filter. \n " \ + " Physica D: Nonlinear Phenomena, 230(1-2), 112-126." \ + "\n " \ + ".. [2] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012)." \ + "\n " \ + " A unification of ensemble square root Kalman filters." \ + "\n " \ + " Monthly Weather Review, 140, 2335-2345.\n " \ + " doi:10.1175/MWR-D-11-00102.1" +docstrings['assimilate_lseik'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.localomi_assimilate`\n "\ + "or :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied\n " \ + "functions and improved efficiency.\n\n " \ + "Local singular evolutive interpolated Kalman filter [1]_\n " \ + "for a single DA step.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.put_state_lseik` " \ + "and :func:`pyPDAF.PDAF.get_state`\n\n "\ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_n_domains_p_pdaf\n " \ + " 4. py__init_dim_obs_pdaf\n " \ + " 5. py__obs_op_pdaf (for each ensemble member)\n " \ + " 6. py__init_obs_pdaf\n "\ + " (if global adaptive forgetting factor `type_forget=1`" \ + "\n " \ + " is used in :func:`pyPDAF.PDAF.init`)\n " \ + " 7. py__init_obsvar_pdaf\n "\ + " (if global adaptive forgetting factor is used)\n " \ + " 8. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_state_pdaf\n " \ + " 4. py__g2l_obs_pdaf (localise mean ensemble\n " \ + " in observation space)\n " \ + " 5. py__init_obs_l_pdaf\n "\ + " 6. py__g2l_obs_pdaf\n "\ + " (localise each ensemble member in observation space)" \ + "\n " \ + " 7. py__init_obsvar_l_pdaf\n "\ + " (only called if local adaptive forgetting\n " \ + " factor `type_forget=2` is used)\n "\ + " 8. py__prodRinvA_l_pdaf\n " \ + " 9. core DA algorithm\n " \ + " 10. py__l2g_state_pdaf\n " \ + " 9. py__prepoststep_state_pdaf\n " \ + " 10. py__distribute_state_pdaf\n " \ + " 11. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.localomi_assimilate`\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Pham, D. T., Verron, J., & Roubaud, M. C. (1998).\n " \ + " A singular evolutive extended Kalman filter\n " \ + " for data assimilation\n "\ + " in oceanography. Journal of Marine systems,\n " \ + " 16(3-4), 323-340." +docstrings['assimilate_lnetf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.localomi_assimilate`\n "\ + "or :func:`pyPDAF.PDAF.localomi_assimilate_lnetf_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "Local Nonlinear Ensemble Transform Filter (LNETF) [1]_\n " \ + "for a single DA step.\n " \ + "The nonlinear filter computes the distribution up to\n " \ + "the second moment similar to Kalman filters but\n " \ + "it uses a nonlinear weighting similar to\n " \ + "particle filters. This leads to an equal weights assumption\n " \ + "for the prior ensemble at each step.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.put_state_lnetf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_n_domains_p_pdaf\n " \ + " 4. py__init_dim_obs_pdaf\n " \ + " 5. py__obs_op_pdaf (for each ensemble member)\n " \ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_state_pdaf\n " \ + " 4. py__init_obs_l_pdaf\n "\ + " 5. py__g2l_obs_pdaf (localise each ensemble\n " \ + " member in observation space)\n " \ + " 6. py__likelihood_l_pdaf\n " \ + " 7. core DA algorithm\n " \ + " 8. py__l2g_state_pdaf\n " \ + " 7. py__prepoststep_state_pdaf\n " \ + " 8. py__distribute_state_pdaf\n " \ + " 9. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.localomi_assimilate`\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_lnetf_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Tödter, J., and B. Ahrens, 2015:\n "\ + " A second-order exact ensemble square root filter\n " \ + " for nonlinear data assimilation. Mon. Wea. Rev.,\n " \ + " 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1." +docstrings['assimilate_lknetf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.localomi_assimilate`\n "\ + "or :func:`pyPDAF.PDAF.localomi_assimilate_lknetf_nondiagR`." \ + "\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "A hybridised LETKF and LNETF [1]_ for a single DA step.\n " \ + "The LNETF computes the distribution up to\n " \ + "the second moment similar to Kalman filters but\n " \ + "using a nonlinear weighting similar to\n " \ + "particle filters. This leads to an equal weights\n " \ + "assumption for the prior ensemble.\n " \ + "The hybridisation with LETKF is expected to lead to\n " \ + "improved performance for quasi-Gaussian problems.\n " \ + "The function should be called at each model step.\n\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.put_state_lknetf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_n_domains_p_pdaf\n " \ + " 4. py__init_dim_obs_pdaf\n " \ + " 5. py__obs_op_pdaf\n "\ + " (for each ensemble member)\n " \ + " 6. py__init_obs_pdaf\n " \ + " (if global adaptive forgetting factor `type_forget=1`" \ + "\n "\ + " is used in :func:`pyPDAF.PDAF.init`)\n " \ + " 7. py__init_obsvar_pdaf (if global adaptive\n " \ + " forgetting factor is used)\n " \ + " 8. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_state_pdaf\n " \ + " 4. py__g2l_obs_pdaf\n "\ + " (localise each ensemble member\n " \ + " in observation space)\n " \ + " 5. py__init_obs_l_pdaf\n "\ + " 6. py__init_obsvar_l_pdaf\n "\ + " (only called if local adaptive forgetting\n " \ + " factor `type_forget=2` is used)\n "\ + " 7. py__prodRinvA_pdaf\n " \ + " 8. py__likelihood_l_pdaf\n " \ + " 9. core DA algorithm\n " \ + " 10. py__l2g_state_pdaf\n " \ + " 9. py__obs_op_pdaf\n " \ + " (only called with `HKN` and `HNK` options\n " \ + " called for each ensemble member)\n " \ + " 10. py__likelihood_hyb_l_pda\n " \ + " 11. py__init_obsvar_l_pdaf\n " \ + " (only called if local adaptive forgetting\n " \ + " factor `type_forget=2` is used)\n "\ + " 12. py__prodRinvA_hyb_l_pdaf\n " \ + " 13. py__prepoststep_state_pdaf\n " \ + " 14. py__distribute_state_pdaf\n " \ + " 15. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.localomi_assimilate`\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_lknetf_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L.. (2022) \n " \ + " Data assimilation for nonlinear systems with\n " \ + " a hybrid nonlinear Kalman ensemble transform filter." \ + "\n " \ + " Q J R Meteorol Soc, 620–640. doi:10.1002/qj.4221" +docstrings['assimilate_prepost'] = \ + "It is used to preprocess and postprocess of the ensemble." \ + "\n\n " \ + "No DA is performed in this function.\n " \ + "Compared to :func:`pyPDAF.PDAF.prepost`,\n " \ + "this function sets assimilation flag, \n " \ + "which means that it is acted as an assimilation in PDAF." \ + "\n\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.put_state_prepost`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n "\ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf (preprocess, step < 0)\n " \ + " 3. py__prepoststep_state_pdaf (postprocess, step > 0)\n " \ + " 4. py__distribute_state_pdaf\n " \ + " 5. py__next_observation_pdaf" +docstrings['generate_obs'] = \ + "Generation of synthetic observations based on\n " \ + "given error statistics and observation operator.\n\n " \ + "When diagonal observation error covariance matrix is used,\n " \ + "it is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_generate_obs` functionalities\n "\ + "for fewer user-supplied functions and improved efficiency.\n\n " \ + "The generated synthetic observations are based on\n " \ + "each member of model forecast.\n " \ + "Therefore, an ensemble of observations can be obtained.\n " \ + "In a typical experiment,\n "\ + "one may only need one ensemble member.\n " \ + "The implementation strategy is similar to\n " \ + "an assimilation step. This means that, \n " \ + "one can reuse many user-supplied functions for\n " \ + "assimilation and observation generation.\n\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.put_state_generate_obs`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n "\ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pda\n " \ + " 5. py__init_obserr_f_pdaf\n " \ + " 6. py__get_obs_f_pdaf\n " \ + " 7. py__prepoststep_state_pdaf\n " \ + " 8. py__distribute_state_pdaf\n " \ + " 9. py__next_observation_pdaf" diff --git a/pyPDAF/source/tool/docstring/pdaf_diag_docstrings.py b/pyPDAF/source/tool/docstring/pdaf_diag_docstrings.py new file mode 100644 index 0000000000000000000000000000000000000000..2c063dc62510531d9e70fb959ffe783d528f2fd8 --- /dev/null +++ b/pyPDAF/source/tool/docstring/pdaf_diag_docstrings.py @@ -0,0 +1,108 @@ +"""Generate the docstrings for the diagnostic routines +""" + + +docstrings = {} + +docstrings['diag_effsample'] = \ + "Calculating the effective sample size of a particle filter.\n" \ + "\n " \ + "Based on [1]_, it is defined as the" \ + "\n " \ + "inverse of the sum of the squared particle filter weights:" \ + "\n " \ + r":math:`N_{eff} = \frac{1}{\sum_{i=1}^{N} w_i^2}`" \ + "\n " \ + r"where :math:`w_i` is the weight of particle with index i." \ + "\n " \ + r"and :math:`N` is the number of particles." \ + "\n\n " \ + r"If the :math:`N_{eff}=N`, all weights are identical," \ + "\n " \ + "and the filter has no influence on the analysis." \ + "\n " \ + r"If :math:`N_{eff}=0`, the filter is collapsed.""\n\n " \ + "This is typically called during the analysis step" \ + "\n " \ + "of a particle filter,\n "\ + "e.g. in the analysis step of NETF and LNETF.\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Doucet, A., de Freitas, N., Gordon, N. (2001). \n "\ + " An Introduction to Sequential Monte Carlo Methods." \ + "\n " \ + " In: Doucet, A., de Freitas, N., Gordon, N. (eds)" \ + "\n " \ + " Sequential Monte Carlo Methods in Practice.\n " \ + " Statistics for Engineering and Information Science." \ + "\n " \ + " Springer, New York, NY." \ + "\n " \ + " https://doi.org/10.1007/978-1-4757-3437-9_1" + +docstrings['diag_ensstats'] = \ + "Computing the skewness and kurtosis of" \ + "\n " \ + "the ensemble of a given element of the state vector.\n" \ + "\n " \ + "The definition used for kurtosis follows that used by [1]_.\n" \ + "\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Lawson, W. G., & Hansen, J. A. (2004).\n " \ + " Implications of stochastic and deterministic" \ + "\n " \ + " filters as ensemble-based\n "\ + " data assimilation methods in varying regimes" \ + "\n " \ + " of error growth.\n "\ + " Monthly weather review, 132(8), 1966-1981." + +docstrings['diag_histogram'] = \ + "Computing the rank histogram of an ensemble.\n" \ + "\n " \ + "A rank histogram is used to diagnose\n " \ + "the reliability of the ensemble [1]_.\n " \ + "A perfectly reliable ensemble should have\n " \ + "a uniform rank histogram.\n\n " \ + "The function can be called in the\n " \ + "pre/poststep routine of PDAF\n "\ + "both before and after the analysis step\n " \ + "to collect the histogram information.\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Hamill, T. M. (2001).\n " \ + " Interpretation of rank histograms\n " \ + " for verifying ensemble forecasts.\n " \ + " Monthly Weather Review, 129(3), 550-560." + +docstrings['diag_CRPS_nompi'] = \ + "A continuous rank probability score for" \ + "\n " \ + "an ensemble without using MPI parallelisation.\n" \ + "\n " \ + "The implementation is based on [1]_.\n" \ + "\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Hersbach, H. (2000), \n "\ + " Decomposition of the Continuous Ranked Probability" \ + "\n " \ + " Score for\n " \ + " Ensemble Prediction Systems,\n " \ + " Wea. Forecasting, 15, 559–570,\n " \ + " doi:10.1175/1520-0434(2000)015<0559:DOTCRP>2.0.CO;2" + +docstrings['diag_CRPS'] = \ + "Obtain a continuous rank probability score for an ensemble.\n" \ + "\n " \ + "The implementation is based on [1]_.\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Hersbach, H. (2000), \n "\ + " Decomposition of the Continuous Ranked Probability" \ + "\n " \ + " Score for\n " \ + " Ensemble Prediction Systems,\n " \ + " Wea. Forecasting, 15, 559–570,\n " \ + " doi:10.1175/1520-0434(2000)015<0559:DOTCRP>2.0.CO;2" diff --git a/pyPDAF/source/tool/docstring/pdaf_put_state_docstrings.py b/pyPDAF/source/tool/docstring/pdaf_put_state_docstrings.py new file mode 100644 index 0000000000000000000000000000000000000000..1eaaea8824d5a6135ff8222f327965a448be3ee3 --- /dev/null +++ b/pyPDAF/source/tool/docstring/pdaf_put_state_docstrings.py @@ -0,0 +1,1012 @@ +"""docstrings for PDAF_put_state_xxx functions + +These functions are mostly deprecated. +""" + +docstrings = {} + +docstrings['put_state_3dvar'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_put_state_3dvar`\n "\ + "or :func:`pyPDAF.PDAF.omi_put_state_3dvar_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied\n " \ + "functions and improved efficiency.\n\n " \ + "3DVar DA for a single DA step.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.assimilate_3dvar`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will not\n " \ + "be assigned by user-supplied functions as well.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "When 3DVar is used, the background error covariance matrix\n "\ + "has to be modelled for cotrol variable transformation.\n " \ + "This is a deterministic filtering scheme so no ensemble\n " \ + "and parallelisation is needed.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. Iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__prodRinvA_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_pdaf\n " \ + " 6. core DA algorithm\n " \ + " 7. py__cvt_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.omi_put_state_3dvar`\n " \ + " and :func:`pyPDAF.PDAF.omi_put_state_3dvar_nondiagR`" +docstrings['put_state_en3dvar_estkf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_put_state_en3dvar_estkf`\n "\ + "or :func:`pyPDAF.PDAF.omi_put_state_en3dvar_estkf_nondiagR`." \ + "\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "3DEnVar for a single DA step.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.assimilate_en3dvar_estkf`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will not be\n " \ + "assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The background error covariance matrix is\n " \ + "estimated by an ensemble.\n " \ + "The 3DEnVar only calculates the analysis of the ensemble mean.\n " \ + "An ESTKF is used along with 3DEnVar to\n " \ + "generate ensemble perturbations.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. the iterative optimisation:\n " \ + " 1. py__cvt_ens_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__prodRinvA_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_ens_pdaf\n " \ + " 6. core 3DEnVar algorithm\n " \ + " 7. py__cvt_ens_pdaf\n " \ + " 8. ESTKF:\n " \ + " 1. py__init_dim_obs_pdaf\n " \ + " 2. py__obs_op_pdaf (for ensemble mean)\n " \ + " 3. py__init_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for each ensemble member)\n " \ + " 5. py__init_obsvar_pdaf\n " \ + " (only relevant for adaptive forgetting factor schemes)\n " \ + " 6. py__prodRinvA_pdaf\n " \ + " 7. core ESTKF algorithm\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.omi_put_state_en3dvar_estkf`\n " \ + " and :func:`pyPDAF.PDAF.omi_put_state_en3dvar_estkf_nondiagR`" +docstrings['put_state_en3dvar_lestkf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "3DEnVar for a single DA step without post-processing,\n " \ + "distributing analysis, and setting next observation step,\n "\ + "where the ensemble anomaly is generated by LESTKF.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.assimilate_en3dvar_lestkf`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The background error covariance matrix is estimated by ensemble.\n " \ + "The 3DEnVar only calculates the analysis of the ensemble mean.\n " \ + "An LESTKF is used to generate ensemble perturbations.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. Starting the iterative optimisation:\n " \ + " 1. py__cvt_ens_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__prodRinvA_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_ens_pdaf\n " \ + " 6. core DA algorithm\n " \ + " 7. py__cvt_ens_pdaf\n " \ + " 8. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n "\ + " (for each ensemble member)\n " \ + " 4. py__init_obs_pdaf\n "\ + " (if global adaptive forgetting factor is used\n "\ + " `type_forget=1` in :func:`pyPDAF.PDAF.init`)\n " \ + " 5. py__init_obsvar_pdaf\n "\ + " (if global adaptive forgetting factor is used)\n " \ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_state_pdaf\n " \ + " 4. py__g2l_obs_pdaf\n "\ + " (localise mean ensemble in observation space)\n " \ + " 5. py__init_obs_l_pdaf\n "\ + " 6. py__g2l_obs_pdaf\n " \ + " (localise each ensemble member in observation space)\n " \ + " 7. py__init_obsvar_l_pdaf\n " \ + " (only called if local adaptive forgetting factor\n " \ + " `type_forget=2` is used)\n "\ + " 8. py__prodRinvA_l_pdaf\n " \ + " 9. core DA algorithm\n " \ + " 10. py__l2g_state_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf_nondiagR`" +docstrings['put_state_hyb3dvar_estkf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_estkf`\n "\ + "or :func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_estkf_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "Hybrid 3DEnVar for a single DA step where\n " \ + "the background error covariance is hybridised by\n " \ + "a static background error covariance,\n " \ + "and a flow-dependent background error covariance\n " \ + "estimated from ensemble.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.assimilate_hyb3dvar_estkf`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The 3DVar generates an ensemble mean and\n " \ + "the ensemble perturbation is generated by\n " \ + "ESTKF in this implementation.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. the iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__cvt_ens_pdaf\n " \ + " 3. py__obs_op_lin_pdaf\n " \ + " 4. py__prodRinvA_pdaf\n " \ + " 5. py__obs_op_adj_pdaf\n " \ + " 6. py__cvt_adj_pdaf\n " \ + " 7. py__cvt_adj_ens_pdaf\n " \ + " 8. core 3DEnVar algorithm\n " \ + " 7. py__cvt_pdaf\n " \ + " 8. py__cvt_ens_pdaf\n " \ + " 9. Perform ESTKF:\n " \ + " 1. py__init_dim_obs_pdaf\n " \ + " 2. py__obs_op_pdaf\n "\ + " (for ensemble mean)\n " \ + " 3. py__init_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " (for each ensemble member)\n " \ + " 5. py__init_obsvar_pdaf\n " \ + " (only relevant for adaptive\n " \ + " forgetting factor schemes)\n " \ + " 6. py__prodRinvA_pdaf\n " \ + " 7. core ESTKF algorithm\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_estkf`\n " \ + " and :func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_estkf_nondiagR`" +docstrings['put_state_hyb3dvar_lestkf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "Hybrid 3DEnVar for a single DA step using\n " \ + "non-diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n " \ + "and setting next observation step, where\n " \ + "the background error covariance is hybridised by\n " \ + "a static background error covariance,\n " \ + "and a flow-dependent background error covariance\n " \ + "estimated from ensemble.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.assimilate_hyb3dvar_lestkf`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The 3DVar generates an ensemble mean and\n " \ + "the ensemble perturbation is generated by\n " \ + "LESTKF in this implementation.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. The iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__cvt_ens_pdaf\n " \ + " 3. py__obs_op_lin_pdaf\n " \ + " 4. py__prodRinvA_pdaf\n " \ + " 5. py__obs_op_adj_pdaf\n " \ + " 6. py__cvt_adj_pdaf\n " \ + " 7. py__cvt_adj_ens_pdaf\n " \ + " 8. core DA algorithm\n " \ + " 7. py__cvt_pdaf\n " \ + " 8. py__cvt_ens_pdaf\n " \ + " 9. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n " \ + " (for each ensemble member)\n " \ + " 4. py__init_obs_pdaf\n " \ + " (if global adaptive forgetting factor\n " \ + " `type_forget=1` in :func:`pyPDAF.PDAF.init`)\n " \ + " 5. py__init_obsvar_pdaf\n " \ + " (if global adaptive forgetting factor is used)\n " \ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_state_pdaf\n " \ + " 4. py__g2l_obs_pdaf\n "\ + " (localise mean ensemble in observation space)\n " \ + " 5. py__init_obs_l_pdaf\n "\ + " 6. py__g2l_obs_pdaf\n " \ + " (localise each ensemble member\n " \ + " in observation space)\n " \ + " 7. py__init_obsvar_l_pdaf\n " \ + " (only called if local adaptive forgetting\n " \ + " factor `type_forget=2` is used)\n "\ + " 8. py__prodRinvA_l_pdaf\n " \ + " 9. core DA algorithm\n " \ + " 10. py__l2g_state_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf_nondiagR`" +docstrings['put_state_enkf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_put_state_global`\n "\ + "or :func:`pyPDAF.PDAF.omi_put_state_enkf_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "Stochastic EnKF (ensemble " \ + "Kalman filter) [1]_ for a single DA step without OMI.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.assimilate_enkf`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "This function should be called at each model time step. \n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for ensemble mean)\n " \ + " 5. py__add_obs_err_pdaf\n " \ + " 6. py__init_obs_pdaf\n " \ + " 7. py__init_obscovar_pdaf\n " \ + " 8. py__obs_op_pdaf (for each ensemble member)\n " \ + " 9. core DA algorithm\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.omi_put_state_global`\n " \ + " and :func:`pyPDAF.PDAF.omi_put_state_enkf_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Evensen, G. (1994), \n "\ + " Sequential data assimilation with a\n " \ + " nonlinear quasi-geostrophic model\n "\ + " using Monte Carlo methods to forecast error statistics,\n "\ + " J. Geophys. Res., 99(C5), 10143–10162, doi:10.1029/94JC00572." +docstrings['put_state_estkf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_put_state_global`\n " \ + "or :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR`\n " \ + "instead of this function.\n\n " \ + "OMI functions need fewer user-supplied functions\n " \ + "and improve DA efficiency.\n\n " \ + "This function calls ESTKF\n " \ + "(error space transform Kalman filter) [1]_.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.assimilate_estkf`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The ESTKF is a more efficient equivalent to the ETKF.\n\n " \ + "The function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for ensemble mean)\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. py__obs_op_pdaf (for each ensemble member)\n " \ + " 7. py__init_obsvar_pdaf (only relevant for\n " \ + " adaptive forgetting factor schemes)\n " \ + " 8. py__prodRinvA_pdaf\n " \ + " 9. core DA algorithm\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.omi_put_state_global`\n " \ + " and :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR`." \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345. doi:10.1175/MWR-D-11-00102.1" +docstrings['put_state_etkf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_put_state_global`\n "\ + "or :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR`.\n\n "\ + "PDAFlocal-OMI modules require fewer user-supplied\n " \ + "functions and improved efficiency.\n\n " \ + "Using ETKF (ensemble transform " \ + "Kalman filter) [1]_ for a single DA step without OMI.\n " \ + "The implementation is baed on [2]_.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.assimilate_etkf`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for ensemble mean)\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. py__obs_op_pdaf (for each ensemble member)\n " \ + " 7. py__init_obsvar_pdaf (only relevant for\n " \ + " adaptive forgetting factor schemes)\n " \ + " 8. py__prodRinvA_pdaf\n " \ + " 9. core DA algorithm\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.omi_put_state_global`\n " \ + " and :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Bishop, C. H., B. J. Etherton, and S. J. Majumdar (2001)\n "\ + " Adaptive Sampling with the Ensemble Transform Kalman Filter.\n "\ + " Part I: Theoretical Aspects. Mon. Wea. Rev., 129, 420–436,\n "\ + " doi: 10.1175/1520-0493(2001)129<0420:ASWTET>2.0.CO;2. \n " \ + ".. [2] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345. doi:10.1175/MWR-D-11-00102.1" +docstrings['put_state_seek'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_put_state_global`\n "\ + "or :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "This function will use\n " \ + "singular evolutive extended Kalman filter [1]_ for\n " \ + "a single DA step.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.assimilate_seek`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "This is a deterministic Kalman filter.\n " \ + "The function should be called at each model step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for ensemble mean)\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. py__obs_op_pdaf (for each ensemble member)\n " \ + " 7. py__prodRinvA_pdaf\n " \ + " 8. core DA algorithm\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.omi_put_state_global`\n " \ + " and :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Pham, D. T., Verron, J., & Roubaud, M. C. (1998).\n "\ + " A singular evolutive extended Kalman filter for data assimilation\n "\ + " in oceanography. Journal of Marine systems, 16(3-4), 323-340." +docstrings['put_state_seik'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_put_state_global`\n "\ + "or :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "This function will use\n " \ + "singular evolutive interpolated Kalman filter [1]_ for\n " \ + "a single DA step.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.assimilate_seik`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions.\n " \ + "The next DA step will not be assigned by user-supplied\n " \ + "functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The function should be called at each model step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for ensemble mean)\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. py__obs_op_pdaf (for each ensemble member)\n " \ + " 7. py__init_obsvar_pdaf (only relevant for\n " \ + " adaptive forgetting factor schemes)\n " \ + " 8. py__prodRinvA_pdaf\n " \ + " 9. core DA algorithm\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.omi_put_state_global`\n " \ + " and :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Pham, D. T., Verron, J., & Roubaud, M. C. (1998).\n "\ + " A singular evolutive extended Kalman filter\n " \ + " for data assimilation\n "\ + " in oceanography. Journal of Marine systems, 16(3-4), 323-340." +docstrings['put_state_netf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_put_state_global`\n "\ + "or :func:`pyPDAF.PDAF.omi_put_state_nonlin_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "This function will use\n " \ + "Nonlinear Ensemble Transform Filter (NETF) [1]_ \n " \ + "for a single DA step.\n\n "\ + "Compared to :func:`pyPDAF.PDAF.assimilate_netf`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The nonlinear filter computes the distribution up to\n " \ + "the second moment similar to KF but using\n " \ + "a nonlinear weighting similar to\n " \ + "particle filter. This leads to an equal weights\n " \ + "assumption for prior ensemble.\n " \ + "The function should be called at each model step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__init_obs_pdaf\n " \ + " 5. py__obs_op_pdaf (for each ensemble member)\n " \ + " 6. py__likelihood_pdaf\n " \ + " 7. core DA algorithm\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.omi_put_state_global`\n " \ + " and :func:`pyPDAF.PDAF.omi_put_state_nonlin_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Tödter, J., and B. Ahrens, 2015:\n "\ + " A second-order exact ensemble square root filter\n " \ + " for nonlinear data assimilation. Mon. Wea. Rev.,\n " \ + " 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1." +docstrings['put_state_pf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_put_state_global`\n "\ + "or :func:`pyPDAF.PDAF.omi_put_state_nonlin_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "This function will use particle filter for a single DA step.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.assimilate_pf`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "This is a fully nonlinear filter, and may require\n " \ + "a high number of ensemble members.\n " \ + "A review of particle filter can be found at [1]_.\n " \ + "The function should be called at each model step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__init_obs_pdaf\n " \ + " 5. py__obs_op_pdaf (for each ensemble member)\n " \ + " 6. py__likelihood_pdaf\n " \ + " 7. core DA algorithm\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.omi_put_state_global`\n " \ + " and :func:`pyPDAF.PDAF.omi_put_state_nonlin_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Van Leeuwen, P. J., Künsch, H. R., Nerger, L.,\n " \ + " Potthast, R., & Reich, S. (2019).\n "\ + " Particle filters for high‐dimensional\n " \ + " geoscience applications:\n "\ + " A review. \n " \ + " Quarterly Journal of the Royal Meteorological Society,\n " \ + " 145(723), 2335-2365." +docstrings['put_state_lenkf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_put_state_lenkf`\n "\ + "or :func:`pyPDAF.PDAF.omi_put_state_lenkf_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "Stochastic EnKF (ensemble Kalman filter)\n " \ + "with covariance localisation [1]_\n " \ + "for a single DA step without OMI.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.assimilate_lenkf`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "This is the only scheme for covariance localisation in PDAF." \ + "\n\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for each ensemble member)\n " \ + " 5. py__localize_pdaf\n " \ + " 6. py__add_obs_err_pdaf\n " \ + " 7. py__init_obs_pdaf\n " \ + " 8. py__init_obscovar_pdaf\n " \ + " 9. py__obs_op_pdaf (repeated to reduce storage)\n " \ + " 10. core DA algorith\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.omi_put_state_lenkf`\n " \ + " and :func:`pyPDAF.PDAF.omi_put_state_lenkf_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Houtekamer, P. L., and H. L. Mitchell (1998): \n " \ + " Data Assimilation Using an Ensemble Kalman\n " \ + " Filter Technique.\n "\ + " Mon. Wea. Rev., 126, 796–811,\n "\ + " doi: 10.1175/1520-0493(1998)126<0796:DAUAEK>2.0.CO;2." +docstrings['put_state_lestkf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.localomi_put_state`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`.\n\n "\ + "PDAFlocal-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "Local ESTKF (error space transform " \ + "Kalman filter) [1]_ for a single DA step without OMI.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.assimilate_lestkf`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The LESTKF is a more efficient equivalent to the LETKF.\n\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. py__init_obs_pdaf\n " \ + " (if global adaptive forgetting factor `type_forget=1` is used\n " \ + " in :func:`pyPDAF.PDAF.init`)\n "\ + " 7. py__init_obsvar_pdaf (if global adaptive\n " \ + " forgetting factor is used)\n "\ + " 8. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__g2l_state_pdaf\n "\ + " 4. py__g2l_obs_pdaf (localise mean ensemble\n " \ + " in observation space)\n "\ + " 5. py__init_obs_l_pdaf\n " \ + " 6. py__g2l_obs_pdaf\n "\ + " (localise each ensemble member in observation space)\n "\ + " 7. py__init_obsvar_l_pdaf\n " \ + " (only called if local adaptive forgetting factor\n " \ + " `type_forget=2` is used)\n " \ + " 8. py__prodRinvA_l_pdaf\n "\ + " 9. core DA algorithm\n " \ + " 10. py__l2g_state_pdaf\n"\ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.localomi_put_state`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345.\n " \ + " doi:10.1175/MWR-D-11-00102.1" +docstrings['put_state_letkf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.localomi_put_state`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`.\n\n "\ + "PDAFlocal-OMI modules require fewer user-supplied\n " \ + "functions and improved efficiency.\n\n " \ + "Local ensemble transform Kalman filter (LETKF) [1]_\n " \ + "for a single DA step without OMI.\n " \ + "Implementation is based on [2]_.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.assimilate_letkf`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "Note that the LESTKF is a more efficient equivalent to the LETKF.\n\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. py__init_obs_pdaf\n " \ + " (if global adaptive forgetting factor\n " \ + " `type_forget=1` is used\n " \ + " in :func:`pyPDAF.PDAF.init`)\n "\ + " 7. py__init_obsvar_pdaf (if global adaptive forgetting\n " \ + " factor is used)\n "\ + " 8. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__g2l_state_pdaf\n "\ + " 4. py__g2l_obs_pdaf (localise mean ensemble\n " \ + " in observation space)\n "\ + " 5. py__init_obs_l_pdaf\n " \ + " 6. py__g2l_obs_pdaf (localise each ensemble member\n " \ + " in observation space)\n "\ + " 7. py__init_obsvar_l_pdaf\n " \ + " (only called if local adaptive forgetting factor\n " \ + " `type_forget=2` is used)\n " \ + " 8. py__prodRinvA_l_pdaf\n "\ + " 9. core DA algorithm\n " \ + " 10. py__l2g_state_pdaf\n"\ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.localomi_put_state`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Hunt, B. R., Kostelich, E. J., & Szunyogh, I. (2007).\n "\ + " Efficient data assimilation for spatiotemporal chaos:\n "\ + " A local ensemble transform Kalman filter. \n "\ + " Physica D: Nonlinear Phenomena, 230(1-2), 112-126.\n " \ + ".. [2] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345.\n " \ + " doi:10.1175/MWR-D-11-00102.1" +docstrings['put_state_lseik'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.localomi_put_state`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "Local singular evolutive interpolated Kalman filter [1]_\n " \ + "for a single DA step.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.assimilate_lseik`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_n_domains_p_pdaf\n " \ + " 4. py__init_dim_obs_pdaf\n " \ + " 5. py__obs_op_pdaf (for each ensemble member)\n " \ + " 6. py__init_obs_pdaf\n "\ + " (if global adaptive forgetting factor `type_forget=1`\n " \ + " is used in :func:`pyPDAF.PDAF.init`)\n " \ + " 7. py__init_obsvar_pdaf\n "\ + " (if global adaptive forgetting factor is used)\n " \ + " 8. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_state_pdaf\n " \ + " 4. py__g2l_obs_pdaf (localise mean ensemble\n " \ + " in observation space)\n " \ + " 5. py__init_obs_l_pdaf\n "\ + " 6. py__g2l_obs_pdaf\n "\ + " (localise each ensemble member in observation space)\n " \ + " 7. py__init_obsvar_l_pdaf\n "\ + " (only called if local adaptive forgetting factor\n " \ + " `type_forget=2` is used)\n "\ + " 8. py__prodRinvA_l_pdaf\n " \ + " 9. core DA algorithm\n " \ + " 10. py__l2g_state_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.localomi_put_state`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Pham, D. T., Verron, J., & Roubaud, M. C. (1998).\n "\ + " A singular evolutive extended Kalman filter for data assimilation\n "\ + " in oceanography. Journal of Marine systems, 16(3-4), 323-340." +docstrings['put_state_lnetf'] = \ + "It is recommended to use :func:`pyPDAF.PDAF.localomi_put_state`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state_lnetf_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "Local Nonlinear Ensemble Transform Filter (LNETF) [1]_\n " \ + "for a single DA step.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.assimilate_lnetf`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The nonlinear filter computes the distribution up to\n " \ + "the second moment similar to Kalman filters\n " \ + "but it uses a nonlinear weighting similar to\n " \ + "particle filters. This leads to an equal weights\n " \ + "assumption for the prior ensemble at each step.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_n_domains_p_pdaf\n " \ + " 4. py__init_dim_obs_pdaf\n " \ + " 5. py__obs_op_pdaf (for each ensemble member)\n " \ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_state_pdaf\n " \ + " 4. py__init_obs_l_pdaf\n "\ + " 5. py__g2l_obs_pdaf (localise each ensemble member\n " \ + " in observation space)\n " \ + " 6. py__likelihood_l_pdaf\n " \ + " 7. core DA algorithm\n " \ + " 8. py__l2g_state_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.localomi_put_state`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_lnetf_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Tödter, J., and B. Ahrens, 2015:\n "\ + " A second-order exact ensemble square root filter\n " \ + " for nonlinear data assimilation. Mon. Wea. Rev.,\n " \ + " 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1." +docstrings['put_state_lknetf'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.localomi_put_state`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state_lknetf_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n " \ + "and improved efficiency.\n\n " \ + "A hybridised LETKF and LNETF [1]_ for a single DA step.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.assimilate_lknetf`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The LNETF computes the distribution up to\n " \ + "the second moment similar to Kalman filters but\n " \ + "using a nonlinear weighting similar to\n " \ + "particle filters. This leads to an equal weights\n " \ + "assumption for the prior ensemble.\n " \ + "The hybridisation with LETKF is expected to lead to\n " \ + "improved performance for\n " \ + "quasi-Gaussian problems.\n " \ + "The function should be called at each model step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_n_domains_p_pdaf\n " \ + " 4. py__init_dim_obs_pdaf\n " \ + " 5. py__obs_op_pdaf\n "\ + " (for each ensemble member)\n " \ + " 6. py__init_obs_pdaf\n " \ + " (if global adaptive forgetting factor `type_forget=1`\n "\ + " is used in :func:`pyPDAF.PDAF.init`)\n " \ + " 7. py__init_obsvar_pdaf (if global adaptive\n " \ + " forgetting factor is used)\n " \ + " 8. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_state_pdaf\n " \ + " 4. py__g2l_obs_pdaf\n "\ + " (localise each ensemble member in observation space)\n " \ + " 5. py__init_obs_l_pdaf\n "\ + " 6. py__init_obsvar_l_pdaf\n "\ + " (only called if local adaptive forgetting factor\n " \ + " `type_forget=2` is used)\n "\ + " 7. py__prodRinvA_pdaf\n " \ + " 8. py__likelihood_l_pdaf\n " \ + " 9. core DA algorithm\n " \ + " 10. py__l2g_state_pdaf\n " \ + " 9. py__obs_op_pdaf\n " \ + " (only called with `HKN` and `HNK` options called\n " \ + " for each ensemble member)\n " \ + " 10. py__likelihood_hyb_l_pda\n " \ + " 11. py__init_obsvar_l_pdaf\n " \ + " (only called if local adaptive forgetting factor\n " \ + " `type_forget=2` is used)\n "\ + " 12. py__prodRinvA_hyb_l_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.localomi_put_state`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_lknetf_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L.. (2022) \n " \ + " Data assimilation for nonlinear systems with\n " \ + " a hybrid nonlinear Kalman ensemble transform filter.\n " \ + " Q J R Meteorol Soc, 620–640. doi:10.1002/qj.4221" +docstrings['put_state_prepost'] = \ + "It is used to preprocess and postprocess of the ensemble.\n\n " \ + "No DA is performed in this function.\n " \ + "Compared to :func:`pyPDAF.PDAF.assimilate_prepost`,\n " \ + "this function does not set assimilation flag, \n " \ + "and does not distribute the processed ensemble to the model field.\n " \ + "This function also does not set the next assimilation step as\n " \ + ":func:`pyPDAF.PDAF.assimilate_prepost`\n " \ + "because it does not call :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf (preprocess, step < 0)" +docstrings['put_state_generate_obs'] = \ + "Generation of synthetic observations\n " \ + "based on given error statistics and observation operator\n " \ + "without post-processing, distributing analysis,\n " \ + "and setting next observation step.\n\n " \ + "When diagonal observation error covariance matrix is used,\n " \ + "it is recommended to use\n " \ + ":func:`pyPDAF.PDAF.omi_generate_obs` functionalities\n "\ + "for fewer user-supplied functions and improved efficiency.\n\n " \ + "The generated synthetic observations are\n " \ + "based on each member of model forecast.\n " \ + "Therefore, an ensemble of observations can be obtained.\n " \ + "In a typical experiment,\n "\ + "one may only need one ensemble member.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.generate_obs`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the next DA step will\n " \ + "not be assigned by user-supplied functions.\n " \ + "This function is typically used when there\n " \ + "are not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The implementation strategy is similar to\n " \ + "an assimilation step. This means that, \n " \ + "one can reuse many user-supplied functions for\n " \ + "assimilation and observation generation.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pda\n " \ + " 5. py__init_obserr_f_pdaf\n " \ + " 6. py__get_obs_f_pdaf" diff --git a/pyPDAF/source/tool/docstring/pdaflocal_assimilate_docstrings.py b/pyPDAF/source/tool/docstring/pdaflocal_assimilate_docstrings.py new file mode 100644 index 0000000000000000000000000000000000000000..2995c43846b92c5b583718544b15ac5d70cb077a --- /dev/null +++ b/pyPDAF/source/tool/docstring/pdaflocal_assimilate_docstrings.py @@ -0,0 +1,854 @@ +"""docstrings for PDAFlocal_assimilate_xxx functions +and PDAFlocal_put_state_xxx functions. + +These functions are mostly deprecated. +""" +docstrings = {} + +docstrings['local_assimilate_en3dvar_lestkf'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf`\n "\ + "or :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n "\ + "and improved efficiency.\n\n " \ + "3DEnVar for a single DA step where the ensemble anomaly\n "\ + "is generated by LESTKF.\n " \ + "The background error covariance matrix is estimated by ensemble.\n " \ + "The 3DEnVar only calculates the analysis of the ensemble mean.\n " \ + "An LESTKF is used to generate ensemble perturbations.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.local_put_state_en3dvar_lestkf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. Starting the iterative optimisation:\n " \ + " 1. py__cvt_ens_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__prodRinvA_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_ens_pdaf\n " \ + " 6. core DA algorithm\n " \ + " 7. py__cvt_ens_pdaf\n " \ + " 8. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n "\ + " (for each ensemble member)\n " \ + " 4. py__init_obs_pdaf\n "\ + " (if global adaptive forgetting factor is used\n "\ + " `type_forget=1` in :func:`pyPDAF.PDAF.init`)\n " \ + " 5. py__init_obsvar_pdaf\n "\ + " (if global adaptive forgetting factor is used)\n " \ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_obs_pdaf\n "\ + " (localise mean ensemble in observation space)\n " \ + " 4. py__init_obs_l_pdaf\n "\ + " 5. py__g2l_obs_pdaf\n " \ + " (localise each ensemble member in observation space)\n " \ + " 6. py__init_obsvar_l_pdaf\n " \ + " (only called if local adaptive forgetting factor\n " \ + " `type_forget=2` is used)\n "\ + " 7. py__prodRinvA_l_pdaf\n " \ + " 8. core DA algorithm\n " \ + " 9. py__prepoststep_state_pdaf\n " \ + " 10. py__distribute_state_pdaf\n " \ + " 11. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf`\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf_nondiagR`" +docstrings['local_assimilate_hyb3dvar_lestkf'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf`\n "\ + "or :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n "\ + "and improved efficiency.\n\n " \ + "Hybrid 3DEnVar for a single DA step where\n " \ + "the background error covariance is hybridised by\n "\ + "a static background error covariance,\n " \ + "and a flow-dependent background error covariance\n "\ + "estimated from ensemble.\n " \ + "The 3DVar generates an ensemble mean and\n "\ + "the ensemble perturbation is generated by\n " \ + "LESTKF in this implementation.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.local_put_state_hyb3dvar_lestkf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. The iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__cvt_ens_pdaf\n " \ + " 3. py__obs_op_lin_pdaf\n " \ + " 4. py__prodRinvA_pdaf\n " \ + " 5. py__obs_op_adj_pdaf\n " \ + " 6. py__cvt_adj_pdaf\n " \ + " 7. py__cvt_adj_ens_pdaf\n " \ + " 8. core DA algorithm\n " \ + " 7. py__cvt_pdaf\n " \ + " 8. py__cvt_ens_pdaf\n " \ + " 9. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n " \ + " (for each ensemble member)\n " \ + " 4. py__init_obs_pdaf\n " \ + " (if global adaptive forgetting factor\n "\ + " `type_forget=1` in :func:`pyPDAF.PDAF.init`)\n " \ + " 5. py__init_obsvar_pdaf\n " \ + " (if global adaptive forgetting factor is used)\n " \ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_obs_pdaf\n "\ + " (localise mean ensemble in observation space)\n " \ + " 4. py__init_obs_l_pdaf\n "\ + " 5. py__g2l_obs_pdaf\n " \ + " (localise each ensemble member\n "\ + " in observation space)\n " \ + " 6. py__init_obsvar_l_pdaf\n " \ + " (only called if local adaptive forgetting\n "\ + " factor `type_forget=2` is used)\n "\ + " 7. py__prodRinvA_l_pdaf\n " \ + " 8. core DA algorithm\n " \ + " 10. py__prepoststep_state_pdaf\n " \ + " 11. py__distribute_state_pdaf\n " \ + " 12. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf`\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf_nondiagR`" +docstrings['local_assimilate_lestkf'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_assimilate`\n "\ + "or :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`.\n\n "\ + "PDAFlocal-OMI modules require fewer user-supplied\n "\ + "functions and improved efficiency.\n\n " \ + "Local ESTKF (error space transform " \ + "Kalman filter) [1]_ for a single DA step without OMI.\n " \ + "The LESTKF is a more efficient equivalent to the LETKF.\n\n " \ + "This function should be called at each model time step.\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.local_put_state_lestkf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. py__init_obs_pdaf\n " \ + " (if global adaptive forgetting factor\n "\ + " `type_forget=1` is used\n " \ + " in :func:`pyPDAF.PDAF.init`)\n "\ + " 7. py__init_obsvar_pdaf (if global adaptive\n "\ + " forgetting factor is used)\n "\ + " 8. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__g2l_obs_pdaf (localise mean ensemble\n "\ + " in observation space)\n "\ + " 4. py__init_obs_l_pdaf\n " \ + " 5. py__g2l_obs_pdaf\n "\ + " (localise each ensemble member\n "\ + " in observation space)\n "\ + " 6. py__init_obsvar_l_pdaf\n " \ + " (only called if local adaptive forgetting\n "\ + " factor `type_forget=2` is used)\n " \ + " 7. py__prodRinvA_l_pdaf\n "\ + " 8. core DA algorithm\n " \ + " 9. py__prepoststep_state_pdaf\n "\ + " 10. py__distribute_state_pdaf\n "\ + " 11. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_assimilate`\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345. doi:10.1175/MWR-D-11-00102.1" +docstrings['local_assimilate_letkf'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_assimilate`\n "\ + "or :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`.\n\n "\ + "PDAFlocal-OMI modules require fewer user-supplied\n "\ + "functions and improved efficiency.\n\n " \ + "Local ensemble transform Kalman filter (LETKF) [1]_ " \ + "for a single DA step without OMI.\n "\ + "Implementation is based on [2]_.\n " \ + "Note that the LESTKF is a more efficient equivalent to the LETKF.\n\n " \ + "This function should be called at each model time step.\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.local_put_state_letkf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. py__init_obs_pdaf\n " \ + " (if global adaptive forgetting factor\n "\ + " `type_forget=1` is used\n " \ + " in :func:`pyPDAF.PDAF.init`)\n "\ + " 7. py__init_obsvar_pdaf (if global adaptive\n "\ + " forgetting factor is used)\n "\ + " 8. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__g2l_obs_pdaf (localise mean ensemble\n "\ + " in observation space)\n "\ + " 4. py__init_obs_l_pdaf\n " \ + " 5. py__g2l_obs_pdaf (localise each ensemble member\n "\ + " in observation space)\n "\ + " 6. py__init_obsvar_l_pdaf\n " \ + " (only called if local adaptive forgetting\n "\ + " factor `type_forget=2` is used)\n " \ + " 7. py__prodRinvA_l_pdaf\n "\ + " 8. core DA algorithm\n " \ + " 9. py__prepoststep_state_pdaf\n "\ + " 10. py__distribute_state_pdaf\n "\ + " 11. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_assimilate`\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Hunt, B. R., Kostelich, E. J., & Szunyogh, I. (2007).\n "\ + " Efficient data assimilation for spatiotemporal chaos:\n "\ + " A local ensemble transform Kalman filter. \n "\ + " Physica D: Nonlinear Phenomena, 230(1-2), 112-126.\n " \ + ".. [2] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345.\n "\ + " doi:10.1175/MWR-D-11-00102.1" +docstrings['local_assimilate_lseik'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_assimilate`\n "\ + "or :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n "\ + "and improved efficiency.\n\n " \ + "Local singular evolutive interpolated Kalman filter [1]_\n "\ + "for a single DA step.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.local_put_state_lseik` " \ + "and :func:`pyPDAF.PDAF.get_state`\n\n "\ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_n_domains_p_pdaf\n " \ + " 4. py__init_dim_obs_pdaf\n " \ + " 5. py__obs_op_pdaf (for each ensemble member)\n " \ + " 6. py__init_obs_pdaf\n "\ + " (if global adaptive forgetting factor `type_forget=1`\n " \ + " is used in :func:`pyPDAF.PDAF.init`)\n " \ + " 7. py__init_obsvar_pdaf\n "\ + " (if global adaptive forgetting factor is used)\n " \ + " 8. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_obs_pdaf (localise mean ensemble\n "\ + " in observation space)\n " \ + " 4. py__init_obs_l_pdaf\n "\ + " 5. py__g2l_obs_pdaf\n "\ + " (localise each ensemble member in observation space)\n " \ + " 6. py__init_obsvar_l_pdaf\n "\ + " (only called if local adaptive forgetting factor\n "\ + " `type_forget=2` is used)\n "\ + " 7. py__prodRinvA_l_pdaf\n " \ + " 8. core DA algorithm\n " \ + " 9. py__prepoststep_state_pdaf\n " \ + " 10. py__distribute_state_pdaf\n " \ + " 11. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_assimilate`\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Pham, D. T., Verron, J., & Roubaud, M. C. (1998).\n "\ + " A singular evolutive extended Kalman filter\n "\ + " for data assimilation\n "\ + " in oceanography. Journal of Marine systems, 16(3-4), 323-340." +docstrings['local_assimilate_lnetf'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_assimilate`\n "\ + "or :func:`pyPDAF.PDAF.localomi_assimilate_lnetf_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n "\ + "and improved efficiency.\n\n " \ + "Local Nonlinear Ensemble Transform Filter (LNETF) [1]_\n "\ + "for a single DA step.\n " \ + "The nonlinear filter computes the distribution up to\n " \ + "the second moment similar to Kalman filters\n "\ + "but it uses a nonlinear weighting similar to\n " \ + "particle filters. This leads to an equal weights\n "\ + "assumption for the prior ensemble at each step.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.local_put_state_lnetf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_n_domains_p_pdaf\n " \ + " 4. py__init_dim_obs_pdaf\n " \ + " 5. py__obs_op_pdaf (for each ensemble member)\n " \ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__init_obs_l_pdaf\n "\ + " 4. py__g2l_obs_pdaf (localise each ensemble member\n "\ + " in observation space)\n " \ + " 5. py__likelihood_l_pdaf\n " \ + " 6. core DA algorithm\n " \ + " 7. py__prepoststep_state_pdaf\n " \ + " 8. py__distribute_state_pdaf\n " \ + " 9. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_assimilate`\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_lnetf_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Tödter, J., and B. Ahrens, 2015:\n "\ + " A second-order exact ensemble square root filter\n " \ + " for nonlinear data assimilation. Mon. Wea. Rev.,\n " \ + " 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1." +docstrings['local_assimilate_lknetf'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_assimilate`\n "\ + "or :func:`pyPDAF.PDAF.localomi_assimilate_lknetf_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n "\ + "and improved efficiency.\n\n " \ + "A hybridised LETKF and LNETF [1]_ for a single DA step.\n " \ + "The LNETF computes the distribution up to\n " \ + "the second moment similar to Kalman filters\n "\ + "but using a nonlinear weighting similar to\n " \ + "particle filters. This leads to an equal weights\n "\ + "assumption for the prior ensemble.\n " \ + "The hybridisation with LETKF is expected to\n "\ + "lead to improved performance for\n " \ + "quasi-Gaussian problems.\n " \ + "The function should be called at each model step.\n\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.local_put_state_lknetf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_n_domains_p_pdaf\n " \ + " 4. py__init_dim_obs_pdaf\n " \ + " 5. py__obs_op_pdaf\n "\ + " (for each ensemble member)\n " \ + " 6. py__init_obs_pdaf\n " \ + " (if global adaptive forgetting factor `type_forget=1`\n "\ + " is used in :func:`pyPDAF.PDAF.init`)\n " \ + " 7. py__init_obsvar_pdaf (if global adaptive\n "\ + " forgetting factor is used)\n " \ + " 8. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_obs_pdaf\n "\ + " (localise each ensemble member in observation space)\n " \ + " 4. py__init_obs_l_pdaf\n "\ + " 5. py__init_obsvar_l_pdaf\n "\ + " (only called if local adaptive forgetting\n "\ + " factor `type_forget=2` is used)\n "\ + " 6. py__prodRinvA_pdaf\n " \ + " 7. py__likelihood_l_pdaf\n " \ + " 8. core DA algorithm\n " \ + " 9. py__obs_op_pdaf\n " \ + " (only called with `HKN` and `HNK` options called\n "\ + " for each ensemble member)\n " \ + " 10. py__likelihood_hyb_l_pda\n " \ + " 11. py__init_obsvar_l_pdaf\n " \ + " (only called if local adaptive forgetting factor\n "\ + " `type_forget=2` is used)\n "\ + " 12. py__prodRinvA_hyb_l_pdaf\n " \ + " 13. py__prepoststep_state_pdaf\n " \ + " 14. py__distribute_state_pdaf\n " \ + " 15. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_assimilate`\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_lknetf_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L.. (2022) \n " \ + " Data assimilation for nonlinear systems with\n "\ + " a hybrid nonlinear Kalman ensemble transform filter. \n " \ + " Q J R Meteorol Soc, 620–640. doi:10.1002/qj.4221" + +docstrings['local_put_state_en3dvar_lestkf'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n "\ + "and improved efficiency.\n\n " \ + "3DEnVar for a single DA step without post-processing,\n "\ + "distributing analysis, and setting next observation step,\n "\ + "where the ensemble anomaly is generated by LESTKF.\n\n " \ + "Compared to\n "\ + ":func:`pyPDAF.PDAF.local_assimilate_en3dvar_lestkf`,\n "\ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n "\ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n "\ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n "\ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n "\ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The background error covariance matrix is estimated by ensemble.\n " \ + "The 3DEnVar only calculates the analysis of the ensemble mean.\n " \ + "An LESTKF is used to generate ensemble perturbations.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. Starting the iterative optimisation:\n " \ + " 1. py__cvt_ens_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__prodRinvA_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_ens_pdaf\n " \ + " 6. core DA algorithm\n " \ + " 7. py__cvt_ens_pdaf\n " \ + " 8. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n "\ + " (for each ensemble member)\n " \ + " 4. py__init_obs_pdaf\n "\ + " (if global adaptive forgetting factor is used\n "\ + " `type_forget=1` in :func:`pyPDAF.PDAF.init`)\n " \ + " 5. py__init_obsvar_pdaf\n "\ + " (if global adaptive forgetting factor is used)\n " \ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_obs_pdaf\n "\ + " (localise mean ensemble in observation space)\n " \ + " 4. py__init_obs_l_pdaf\n "\ + " 5. py__g2l_obs_pdaf\n " \ + " (localise each ensemble member in observation space)\n " \ + " 6. py__init_obsvar_l_pdaf\n " \ + " (only called if local adaptive forgetting factor\n " \ + " `type_forget=2` is used)\n "\ + " 7. py__prodRinvA_l_pdaf\n " \ + " 8. core DA algorithm\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf_nondiagR`" +docstrings['local_put_state_hyb3dvar_lestkf'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n "\ + "and improved efficiency.\n\n " \ + "Hybrid 3DEnVar for a single DA step using\n "\ + "non-diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n "\ + "and setting next observation step, where\n " \ + "the background error covariance is hybridised by\n "\ + "a static background error covariance,\n " \ + "and a flow-dependent background error covariance\n "\ + "estimated from ensemble.\n\n " \ + "Compared to\n "\ + ":func:`pyPDAF.PDAF.local_assimilate_hyb3dvar_lestkf`,\n "\ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n "\ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n "\ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n "\ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n "\ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The 3DVar generates an ensemble mean and\n "\ + "the ensemble perturbation is generated by\n " \ + "LESTKF in this implementation.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. The iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__cvt_ens_pdaf\n " \ + " 3. py__obs_op_lin_pdaf\n " \ + " 4. py__prodRinvA_pdaf\n " \ + " 5. py__obs_op_adj_pdaf\n " \ + " 6. py__cvt_adj_pdaf\n " \ + " 7. py__cvt_adj_ens_pdaf\n " \ + " 8. core DA algorithm\n " \ + " 7. py__cvt_pdaf\n " \ + " 8. py__cvt_ens_pdaf\n " \ + " 9. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n " \ + " (for each ensemble member)\n " \ + " 4. py__init_obs_pdaf\n " \ + " (if global adaptive forgetting factor\n "\ + " `type_forget=1` in :func:`pyPDAF.PDAF.init`)\n " \ + " 5. py__init_obsvar_pdaf\n " \ + " (if global adaptive forgetting factor is used)\n " \ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_obs_pdaf\n "\ + " (localise mean ensemble in observation space)\n " \ + " 4. py__init_obs_l_pdaf\n "\ + " 5. py__g2l_obs_pdaf\n " \ + " (localise each ensemble member\n "\ + " in observation space)\n " \ + " 6. py__init_obsvar_l_pdaf\n " \ + " (only called if local adaptive forgetting\n "\ + " factor `type_forget=2` is used)\n "\ + " 7. py__prodRinvA_l_pdaf\n " \ + " 8. core DA algorithm\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf_nondiagR`" +docstrings['local_put_state_lestkf'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_put_state`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`.\n\n "\ + "PDAFlocal-OMI modules require fewer\n "\ + "user-supplied functions and improved efficiency.\n\n " \ + "Local ESTKF (error space transform " \ + "Kalman filter) [1]_ for a single DA step without OMI.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.local_assimilate_lestkf`,\n "\ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n "\ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n "\ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n "\ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n "\ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The LESTKF is a more efficient equivalent to the LETKF.\n\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. py__init_obs_pdaf\n " \ + " (if global adaptive forgetting factor\n "\ + " `type_forget=1` is used\n " \ + " in :func:`pyPDAF.PDAF.init`)\n "\ + " 7. py__init_obsvar_pdaf (if global adaptive\n "\ + " forgetting factor is used)\n "\ + " 8. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__g2l_obs_pdaf (localise mean ensemble\n "\ + " in observation space)\n "\ + " 4. py__init_obs_l_pdaf\n " \ + " 5. py__g2l_obs_pdaf\n "\ + " (localise each ensemble member\n "\ + " in observation space)\n "\ + " 6. py__init_obsvar_l_pdaf\n " \ + " (only called if local adaptive forgetting\n "\ + " factor `type_forget=2` is used)\n " \ + " 7. py__prodRinvA_l_pdaf\n "\ + " 8. core DA algorithm\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_put_state`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345.\n "\ + " doi:10.1175/MWR-D-11-00102.1" +docstrings['local_put_state_letkf'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_put_state`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`.\n\n "\ + "PDAFlocal-OMI modules require fewer user-supplied\n "\ + "functions and improved efficiency.\n\n " \ + "Local ensemble transform Kalman filter (LETKF) [1]_\n " \ + "for a single DA step without OMI. Implementation is\n "\ + "based on [2]_.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.local_assimilate_letkf`,\n "\ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n "\ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n "\ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n "\ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n "\ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "Note that the LESTKF is a more efficient equivalent to the LETKF.\n\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. py__init_obs_pdaf\n " \ + " (if global adaptive forgetting factor\n "\ + " `type_forget=1` is used\n " \ + " in :func:`pyPDAF.PDAF.init`)\n "\ + " 7. py__init_obsvar_pdaf (if global adaptive\n "\ + " forgetting factor is used)\n "\ + " 8. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__g2l_obs_pdaf (localise mean ensemble\n "\ + " in observation space)\n "\ + " 4. py__init_obs_l_pdaf\n " \ + " 5. py__g2l_obs_pdaf (localise each ensemble member\n "\ + " in observation space)\n "\ + " 6. py__init_obsvar_l_pdaf\n " \ + " (only called if local adaptive forgetting\n "\ + " factor `type_forget=2` is used)\n " \ + " 7. py__prodRinvA_l_pdaf\n "\ + " 8. core DA algorithm\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_put_state`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Hunt, B. R., Kostelich, E. J., & Szunyogh, I. (2007).\n "\ + " Efficient data assimilation for spatiotemporal chaos:\n "\ + " A local ensemble transform Kalman filter. \n "\ + " Physica D: Nonlinear Phenomena, 230(1-2), 112-126.\n " \ + ".. [2] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345.\n "\ + " doi:10.1175/MWR-D-11-00102.1" +docstrings['local_put_state_lseik'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_put_state`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n "\ + "and improved efficiency.\n\n " \ + "Local singular evolutive interpolated Kalman filter [1]_\n "\ + "for a single DA step.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.local_assimilate_lseik`,\n "\ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n "\ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n "\ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n "\ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n "\ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_n_domains_p_pdaf\n " \ + " 4. py__init_dim_obs_pdaf\n " \ + " 5. py__obs_op_pdaf (for each ensemble member)\n " \ + " 6. py__init_obs_pdaf\n "\ + " (if global adaptive forgetting factor `type_forget=1`\n " \ + " is used in :func:`pyPDAF.PDAF.init`)\n " \ + " 7. py__init_obsvar_pdaf\n "\ + " (if global adaptive forgetting factor is used)\n " \ + " 8. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_obs_pdaf (localise mean ensemble\n "\ + " in observation space)\n " \ + " 4. py__init_obs_l_pdaf\n "\ + " 5. py__g2l_obs_pdaf\n "\ + " (localise each ensemble member in observation space)\n " \ + " 6. py__init_obsvar_l_pdaf\n "\ + " (only called if local adaptive forgetting\n "\ + " factor `type_forget=2` is used)\n "\ + " 7. py__prodRinvA_l_pdaf\n " \ + " 8. core DA algorithm\n " \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_put_state`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Pham, D. T., Verron, J., & Roubaud, M. C. (1998).\n "\ + " A singular evolutive extended Kalman filter\n "\ + " for data assimilation\n "\ + " in oceanography. Journal of Marine systems, 16(3-4), 323-340." +docstrings['local_put_state_lnetf'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_put_state`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state_lnetf_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n "\ + "and improved efficiency.\n\n " \ + "Local Nonlinear Ensemble Transform Filter (LNETF) [1]_\n "\ + "for a single DA step.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.local_assimilate_lnetf`,\n "\ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n "\ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n "\ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n "\ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n "\ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The nonlinear filter computes the distribution up to\n " \ + "the second moment similar to Kalman filters\n "\ + "but it uses a nonlinear weighting similar to\n " \ + "particle filters. This leads to an equal weights\n "\ + "assumption for the prior ensemble at each step.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_n_domains_p_pdaf\n " \ + " 4. py__init_dim_obs_pdaf\n " \ + " 5. py__obs_op_pdaf (for each ensemble member)\n " \ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__init_obs_l_pdaf\n "\ + " 4. py__g2l_obs_pdaf (localise each ensemble member\n "\ + " in observation space)\n " \ + " 5. py__likelihood_l_pdaf\n " \ + " 6. core DA algorithm\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_put_state`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_lnetf_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Tödter, J., and B. Ahrens, 2015:\n "\ + " A second-order exact ensemble square root filter\n " \ + " for nonlinear data assimilation. Mon. Wea. Rev.,\n " \ + " 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1." +docstrings['local_put_state_lknetf'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_put_state`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state_lknetf_nondiagR`.\n\n "\ + "PDAF-OMI modules require fewer user-supplied functions\n "\ + "and improved efficiency.\n\n " \ + "A hybridised LETKF and LNETF [1]_ for a single DA step.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.local_assimilate_lknetf`,\n "\ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n "\ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n "\ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n "\ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n "\ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The LNETF computes the distribution up to\n " \ + "the second moment similar to Kalman filters\n "\ + "but using a nonlinear weighting similar to\n " \ + "particle filters. This leads to an equal weights\n "\ + "assumption for the prior ensemble.\n " \ + "The hybridisation with LETKF is expected to\n "\ + "lead to improved performance for\n " \ + "quasi-Gaussian problems.\n " \ + "The function should be called at each model step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_n_domains_p_pdaf\n " \ + " 4. py__init_dim_obs_pdaf\n " \ + " 5. py__obs_op_pdaf\n "\ + " (for each ensemble member)\n " \ + " 6. py__init_obs_pdaf\n " \ + " (if global adaptive forgetting factor `type_forget=1`\n "\ + " is used in :func:`pyPDAF.PDAF.init`)\n " \ + " 7. py__init_obsvar_pdaf (if global adaptive\n "\ + " forgetting factor is used)\n " \ + " 8. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_obs_pdaf\n "\ + " (localise each ensemble member\n "\ + " in observation space)\n " \ + " 4. py__init_obs_l_pdaf\n "\ + " 5. py__init_obsvar_l_pdaf\n "\ + " (only called if local adaptive forgetting\n "\ + " factor `type_forget=2` is used)\n "\ + " 6. py__prodRinvA_pdaf\n " \ + " 7. py__likelihood_l_pdaf\n " \ + " 8. core DA algorithm\n " \ + " 9. py__obs_op_pdaf\n " \ + " (only called with `HKN` and `HNK` options\n "\ + " called for each ensemble member)\n " \ + " 10. py__likelihood_hyb_l_pda\n " \ + " 11. py__init_obsvar_l_pdaf\n " \ + " (only called if local adaptive forgetting\n "\ + " factor `type_forget=2` is used)\n "\ + " 12. py__prodRinvA_hyb_l_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_put_state`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_lknetf_nondiagR`" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L.. (2022)\n " \ + " Data assimilation for nonlinear systems with\n "\ + " a hybrid nonlinear Kalman ensemble transform filter." \ + "\n " \ + " Q J R Meteorol Soc, 620–640. doi:10.1002/qj.4221" diff --git a/pyPDAF/source/tool/docstring/pdaflocalomi_assimilate_docstrings.py b/pyPDAF/source/tool/docstring/pdaflocalomi_assimilate_docstrings.py new file mode 100644 index 0000000000000000000000000000000000000000..07ec9708164296454cf624204237359e62cfb2e4 --- /dev/null +++ b/pyPDAF/source/tool/docstring/pdaflocalomi_assimilate_docstrings.py @@ -0,0 +1,300 @@ +"""docstrings for PDAFlocalomi_assimilate_xxx functions +""" +docstrings = {} + +docstrings['localomi_assimilate'] = \ + "Domain local filters for a single DA step\n " \ + "using diagnoal observation error covariance matrix.\n\n " \ + "Here, this function call is used for LE(S)TKF [1]_,\n " \ + "LSEIK [1]_, LNETF [2]_, and LKNETF [3]_.\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n " \ + "This function should be called at each model time step.\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.localomi_put_state_local`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. core DA algorithm\n " \ + " 7. py__prepoststep_state_pdaf\n "\ + " 8. py__distribute_state_pdaf\n "\ + " 9. py__next_observation_pdaf\n" \ + "\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345.\n " \ + " doi:10.1175/MWR-D-11-00102.1\n " \ + ".. [2] Tödter, J., and B. Ahrens, 2015:\n "\ + " A second-order exact ensemble square root filter\n " \ + " for nonlinear data assimilation. Mon. Wea. Rev.,\n " \ + " 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1.\n " \ + ".. [3] Nerger, L.. (2022) \n " \ + " Data assimilation for nonlinear systems with\n " \ + " a hybrid nonlinear Kalman ensemble transform filter. \n " \ + " Q J R Meteorol Soc, 620–640. doi:10.1002/qj.4221" +docstrings['localomi_assimilate_en3dvar_lestkf'] = \ + "3DEnVar for a single DA step where the ensemble anomaly\n " \ + "is generated by LESTKF using diagnoal observation\n " \ + "error covariance matrix.\n\n " \ + "The background error covariance matrix is estimated by ensemble.\n " \ + "The 3DEnVar only calculates the analysis of the ensemble mean.\n " \ + "An LESTKF is used to generate ensemble perturbations.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. Starting the iterative optimisation:\n " \ + " 1. py__cvt_ens_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__obs_op_adj_pdaf\n " \ + " 4. py__cvt_adj_ens_pdaf\n " \ + " 5. core DA algorithm\n " \ + " 6. py__cvt_ens_pdaf\n " \ + " 7. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n "\ + " (for each ensemble member)\n " \ + " 4. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. core DA algorithm\n " \ + " 8. py__prepoststep_state_pdaf\n " \ + " 9. py__distribute_state_pdaf\n " \ + " 10. py__next_observation_pdaf" +docstrings['localomi_assimilate_hyb3dvar_lestkf'] = \ + "Hybrid 3DEnVar for a single DA step\n " \ + "using diagnoal observation error covariance matrix.\n\n " \ + "Here, the background error covariance is hybridised by\n " \ + "a static background error covariance,\n " \ + "and a flow-dependent background error covariance\n " \ + "estimated from ensemble.\n " \ + "The 3DVar generates an ensemble mean and\n " \ + "the ensemble perturbation is generated by\n " \ + "LESTKF in this implementation.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. The iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__cvt_ens_pdaf\n " \ + " 3. py__obs_op_lin_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_pdaf\n " \ + " 6. py__cvt_adj_ens_pdaf\n " \ + " 7. core DA algorithm\n " \ + " 6. py__cvt_pdaf\n " \ + " 7. py__cvt_ens_pdaf\n " \ + " 8. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n " \ + " (for each ensemble member)\n " \ + " 4. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. core DA algorithm\n " \ + " 9. py__prepoststep_state_pdaf\n " \ + " 10. py__distribute_state_pdaf\n " \ + " 11. py__next_observation_pdaf" +docstrings['localomi_assimilate_en3dvar_lestkf_nondiagR'] = \ + "3DEnVar for a single DA step where the ensemble anomaly\n " \ + "is generated by LESTKF using\n " \ + "non-diagnoal observation error covariance matrix.\n\n " \ + "Here, the background error covariance matrix is\n " \ + "estimated by ensemble.\n " \ + "The 3DEnVar only calculates the analysis of the ensemble mean.\n " \ + "An LESTKF is used to generate ensemble perturbations.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf_nondiagR`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. Starting the iterative optimisation:\n " \ + " 1. py__cvt_ens_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__prodRinvA_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_ens_pdaf\n " \ + " 6. core DA algorithm\n " \ + " 6. py__cvt_ens_pdaf\n " \ + " 7. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n "\ + " (for each ensemble member)\n " \ + " 4. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__prodRinvA_l_pdaf\n " \ + " 4. core DA algorithm\n " \ + " 8. py__prepoststep_state_pdaf\n " \ + " 9. py__distribute_state_pdaf\n " \ + " 10. py__next_observation_pdaf" +docstrings['localomi_assimilate_hyb3dvar_lestkf_nondiagR'] = \ + "Hybrid 3DEnVar for a single DA step\n " \ + "using diagnoal observation error covariance matrix.\n\n " \ + "Here, the background error covariance is\n " \ + "hybridised by a static background error covariance,\n " \ + "and a flow-dependent background error covariance\n " \ + "estimated from ensemble.\n " \ + "The 3DVar generates an ensemble mean and\n " \ + "the ensemble perturbation is generated by\n " \ + "LESTKF in this implementation.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf_nondiagR`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. The iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__cvt_ens_pdaf\n " \ + " 3. py__obs_op_lin_pdaf\n " \ + " 4. py__prodRinvA_pdaf\n " \ + " 5. py__obs_op_adj_pdaf\n " \ + " 6. py__cvt_adj_pdaf\n " \ + " 7. py__cvt_adj_ens_pdaf\n " \ + " 8. core DA algorithm\n " \ + " 6. py__cvt_pdaf\n " \ + " 7. py__cvt_ens_pdaf\n " \ + " 8. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n " \ + " (for each ensemble member)\n " \ + " 4. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__prodRinvA_l_pdaf\n " \ + " 4. core DA algorithm\n " \ + " 9. py__prepoststep_state_pdaf\n " \ + " 10. py__distribute_state_pdaf\n " \ + " 11. py__next_observation_pdaf" +docstrings['localomi_assimilate_nondiagR'] = \ + "Domain local filters for a single DA step\n " \ + "using non-diagnoal observation error covariance matrix.\n\n " \ + "Here, this function call is used for LE(S)TKF [1]_ and LSEIK [1]_\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n " \ + "This function should be called at each model time step.\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.localomi_put_state_local_nondiagR`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__init_obs_l_pdaf\n "\ + " 4. py__prodRinvA_l_pdaf\n " \ + " 5. core DA algorithm\n " \ + " 7. py__prepoststep_state_pdaf\n "\ + " 8. py__distribute_state_pdaf\n "\ + " 9. py__next_observation_pdaf\n" \ + "\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345.\n " \ + " doi:10.1175/MWR-D-11-00102.1" +docstrings['localomi_assimilate_lnetf_nondiagR'] = \ + "LNETF for a single DA step using\n " \ + "non-diagnoal observation error covariance matrix.\n\n " \ + "See :func:`pyPDAF.PDAF.localomi_assimilate` for\n " \ + "using diagnoal observation error covariance matrix.\n " \ + "The non-linear filter is proposed in [1]_.\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n " \ + "This function should be called at each model time step.\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.localomi_put_state_lnetf_nondiagR`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__likelihood_l_pdaf\n " \ + " 4. core DA algorithm\n " \ + " 7. py__prepoststep_state_pdaf\n "\ + " 8. py__distribute_state_pdaf\n "\ + " 9. py__next_observation_pdaf\n" \ + "\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Tödter, J., and B. Ahrens, 2015:\n "\ + " A second-order exact ensemble square root filter\n " \ + " for nonlinear data assimilation. Mon. Wea. Rev.,\n " \ + " 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1." +docstrings['localomi_assimilate_lknetf_nondiagR'] = \ + "LKNETF for a single DA step using\n " \ + "non-diagnoal observation error covariance matrix.\n\n " \ + "See :func:`pyPDAF.PDAF.localomi_assimilate` for\n " \ + "using diagnoal observation error covariance matrix.\n " \ + "The non-linear filter is proposed in [1]_.\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n " \ + "This function should be called at each model time step.\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.localomi_put_state_lknetf_nondiagR`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__prodRinvA_pdaf\n " \ + " 4. py__likelihood_l_pdaf\n " \ + " 5. core DA algorithm\n " \ + " 6. py__obs_op_pdaf\n " \ + " (only called with `HKN` and `HNK` options\n " \ + " called for each ensemble member)\n " \ + " 7. py__likelihood_hyb_l_pda\n " \ + " 8. py__prodRinvA_hyb_l_pdaf\n " \ + " 7. py__prepoststep_state_pdaf\n "\ + " 8. py__distribute_state_pdaf\n "\ + " 9. py__next_observation_pdaf\n" \ + "\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L.. (2022) \n " \ + " Data assimilation for nonlinear systems with\n " \ + " a hybrid nonlinear Kalman ensemble transform filter. \n " \ + " Q J R Meteorol Soc, 620–640. doi:10.1002/qj.4221" diff --git a/pyPDAF/source/tool/docstring/pdaflocalomi_put_state_docstrings.py b/pyPDAF/source/tool/docstring/pdaflocalomi_put_state_docstrings.py new file mode 100644 index 0000000000000000000000000000000000000000..873295eed1163230d742330893bbf83315734ba4 --- /dev/null +++ b/pyPDAF/source/tool/docstring/pdaflocalomi_put_state_docstrings.py @@ -0,0 +1,364 @@ +"""docstrings for PDAFlocalomi_put_state_xxx functions +""" +docstrings = {} + +docstrings['localomi_put_state'] = \ + "Domain local filters for a single DA step\n " \ + "using diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n " \ + "and setting next observation step.\n\n " \ + "Here, this function call is used for LE(S)TKF [1]_, \n " \ + "LSEIK [1]_, LNETF [2]_, and LKNETF [3]_.\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n " \ + "Compared to :func:`pyPDAF.PDAF.localomi_assimilate_local`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The LESTKF is a more efficient equivalent to the LETKF.\n\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. core DA algorithm\n" \ + "\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345.\n " \ + " doi:10.1175/MWR-D-11-00102.1\n " \ + ".. [2] Tödter, J., and B. Ahrens, 2015:\n "\ + " A second-order exact ensemble square root filter\n " \ + " for nonlinear data assimilation. Mon. Wea. Rev.,\n " \ + " 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1.\n " \ + ".. [3] Nerger, L.. (2022) \n " \ + " Data assimilation for nonlinear systems with\n " \ + " a hybrid nonlinear Kalman ensemble transform filter. \n " \ + " Q J R Meteorol Soc, 620–640. doi:10.1002/qj.4221" +docstrings['localomi_put_state_en3dvar_lestkf'] = \ + "3DEnVar for a single DA step where\n " \ + "the ensemble anomaly is generated by LESTKF\n " \ + "using diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n " \ + "and setting next observation step.\n\n " \ + "Compared to\n " \ + ":func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The background error covariance matrix is estimated by ensemble.\n " \ + "The 3DEnVar only calculates the analysis of the ensemble mean.\n " \ + "An LESTKF is used to generate ensemble perturbations.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied function are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. Starting the iterative optimisation:\n " \ + " 1. py__cvt_ens_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__obs_op_adj_pdaf\n " \ + " 4. py__cvt_adj_ens_pdaf\n " \ + " 5. core DA algorithm\n " \ + " 6. py__cvt_ens_pdaf\n " \ + " 7. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n "\ + " (for each ensemble member)\n " \ + " 4. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. core DA algorithm" +docstrings['localomi_put_state_hyb3dvar_lestkf'] = \ + "Hybrid 3DEnVar for a single DA step\n " \ + "using diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n " \ + "and setting next observation step.\n\n " \ + "Here, the background error covariance is\n " \ + "hybridised by a static background error covariance,\n " \ + "and a flow-dependent background error covariance\n " \ + "estimated from ensemble.\n\n " \ + "Compared to\n " \ + ":func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The 3DVar generates an ensemble mean and\n " \ + "the ensemble perturbation is generated by\n " \ + "LESTKF in this implementation.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. The iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__cvt_ens_pdaf\n " \ + " 3. py__obs_op_lin_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_pdaf\n " \ + " 6. py__cvt_adj_ens_pdaf\n " \ + " 7. core DA algorithm\n " \ + " 6. py__cvt_pdaf\n " \ + " 7. py__cvt_ens_pdaf\n " \ + " 8. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n " \ + " (for each ensemble member)\n " \ + " 4. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. core DA algorithm" +docstrings['localomi_put_state_en3dvar_lestkf_nondiagR'] = \ + "3DEnVar for a single DA step without post-processing,\n " \ + "distributing analysis, and setting next observation step.\n\n "\ + "Here, the ensemble anomaly is generated by LESTKF\n " \ + "using non-diagnoal observation error covariance matrix.\n\n " \ + "Compared to\n " \ + ":func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf_nondiagR`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The background error covariance matrix is\n " \ + "estimated by ensemble.\n " \ + "The 3DEnVar only calculates the analysis of the ensemble mean." \ + "\n " \ + "An LESTKF is used to generate ensemble perturbations.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied function are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. Starting the iterative optimisation:\n " \ + " 1. py__cvt_ens_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__prodRinvA_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_ens_pdaf\n " \ + " 6. core DA algorithm\n " \ + " 6. py__cvt_ens_pdaf\n " \ + " 7. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n "\ + " (for each ensemble member)\n " \ + " 4. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__prodRinvA_l_pdaf\n " \ + " 4. core DA algorithm" +docstrings['localomi_put_state_hyb3dvar_lestkf_nondiagR'] = \ + "Hybrid 3DEnVar for a single DA step\n " \ + "using non-diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n " \ + "and setting next observation step.\n\n " \ + "Here, the background error covariance is\n " \ + "hybridised by a static background error covariance,\n " \ + "and a flow-dependent background error covariance\n " \ + "estimated from ensemble.\n\n " \ + "Compared to\n " \ + ":func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf_nondiagR`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The 3DVar generates an ensemble mean and\n " \ + "the ensemble perturbation is generated by\n " \ + "LESTKF in this implementation.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. The iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__cvt_ens_pdaf\n " \ + " 3. py__obs_op_lin_pdaf\n " \ + " 4. py__prodRinvA_pdaf\n " \ + " 5. py__obs_op_adj_pdaf\n " \ + " 6. py__cvt_adj_pdaf\n " \ + " 7. py__cvt_adj_ens_pdaf\n " \ + " 8. core DA algorithm\n " \ + " 6. py__cvt_pdaf\n " \ + " 7. py__cvt_ens_pdaf\n " \ + " 8. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n " \ + " (for each ensemble member)\n " \ + " 4. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__prodRinvA_l_pdaf\n " \ + " 4. core DA algorithm" +docstrings['localomi_put_state_nondiagR'] = \ + "Domain local filters for a single DA step\n " \ + "using non-diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n " \ + "and setting next observation step.\n\n " \ + "Here, this function call is used for LE(S)TKF [1]_ and LSEIK [1]_\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n\n " \ + "Compared to\n " \ + ":func:`pyPDAF.PDAF.localomi_assimilate_local_nondiagR`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__init_obs_l_pdaf\n "\ + " 4. py__prodRinvA_l_pdaf\n " \ + " 5. core DA algorithm\n " \ + "\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345.\n " \ + " doi:10.1175/MWR-D-11-00102.1" +docstrings['localomi_put_state_lnetf_nondiagR'] = \ + "LNETF for a single DA step\n " \ + "using non-diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n " \ + "and setting next observation step.\n\n " \ + "See :func:`pyPDAF.PDAF.localomi_put_state`\n " \ + "for using diagnoal observation error covariance matrix.\n " \ + "The non-linear filter is proposed in [1]_.\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n\n " \ + "Compared to\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_lnetf_nondiagR`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__likelihood_l_pdaf\n " \ + " 4. core DA algorithm\n " \ + "\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Tödter, J., and B. Ahrens, 2015:\n "\ + " A second-order exact ensemble square root filter\n " \ + " for nonlinear data assimilation. Mon. Wea. Rev.,\n " \ + " 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1." +docstrings['localomi_put_state_lknetf_nondiagR'] = \ + "LKNETF for a single DA step\n " \ + "using non-diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n " \ + "and setting next observation step.\n\n " \ + "See :func:`pyPDAF.PDAF.localomi_assimilate`\n " \ + "for using diagnoal observation error covariance matrix.\n " \ + "The non-linear filter is proposed in [1]_.\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n\n " \ + "Compared to\n " \ + ":func:`pyPDAF.PDAF.localomi_assimilate_lknetf_nondiagR`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__prodRinvA_pdaf\n " \ + " 4. py__likelihood_l_pdaf\n " \ + " 5. core DA algorithm\n " \ + " 6. py__obs_op_pdaf\n " \ + " (only called with `HKN` and `HNK` options\n " \ + " called for each ensemble member)\n " \ + " 7. py__likelihood_hyb_l_pda\n " \ + " 8. py__prodRinvA_hyb_l_pdaf\n" \ + "\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L.. (2022) \n " \ + " Data assimilation for nonlinear systems with\n " \ + " a hybrid nonlinear Kalman ensemble transform filter.\n " \ + " Q J R Meteorol Soc, 620–640. doi:10.1002/qj.4221" diff --git a/pyPDAF/source/tool/docstring/pdafomi_assimilate_docstrings.py b/pyPDAF/source/tool/docstring/pdafomi_assimilate_docstrings.py new file mode 100644 index 0000000000000000000000000000000000000000..dea3bfbf7732a00fc9aabbc0d8b5f5aee223fa19 --- /dev/null +++ b/pyPDAF/source/tool/docstring/pdafomi_assimilate_docstrings.py @@ -0,0 +1,843 @@ +"""docstrings for PDAFomi_assimilate_xxx functions +""" +docstrings = {} + + +docstrings['omi_assimilate_3dvar'] = \ + "3DVar DA for a single DA step\n "\ + "using diagnoal observation error covariance matrix.\n\n "\ + "See :func:`pyPDAF.PDAF.omi_assimilate_3dvar_nondiagR`\n "\ + "for non-diagonal observation error covariance matrix.\n\n "\ + "When 3DVar is used, the background error covariance matrix\n "\ + "has to be modelled for cotrol variable transformation.\n " \ + "This is a deterministic filtering scheme\n "\ + "so no ensemble and parallelisation is needed.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.omi_put_state_3dvar`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n "\ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. Iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__obs_op_adj_pdaf\n " \ + " 4. py__cvt_adj_pdaf\n " \ + " 5. core DA algorithm\n " \ + " 6. py__cvt_pdaf\n " \ + " 7. py__prepoststep_state_pdaf\n " \ + " 8. py__distribute_state_pdaf\n " \ + " 9. py__next_observation_pdaf" +docstrings['omi_assimilate_en3dvar_estkf'] = \ + "3DEnVar for a single DA step\n "\ + "using diagnoal observation error covariance matrix.\n\n "\ + "See :func:`pyPDAF.PDAF.omi_assimilate_en3dvar_estkf_nondiagR`\n "\ + "for using non-diagonal observation error covariance matirx.\n\n " \ + "Here, the background error covariance matrix is\n "\ + "estimated by an ensemble.\n " \ + "The 3DEnVar only calculates the analysis of the ensemble mean.\n " \ + "An ESTKF is used along with 3DEnVar to generate ensemble perturbations.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.omi_put_state_en3dvar_estkf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. the iterative optimisation:\n " \ + " 1. py__cvt_ens_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__obs_op_adj_pdaf\n " \ + " 4. py__cvt_adj_ens_pdaf\n " \ + " 5. core 3DEnVar algorithm\n " \ + " 6. py__cvt_ens_pdaf\n " \ + " 7. ESTKF:\n " \ + " 1. py__init_dim_obs_pdaf\n " \ + " 2. py__obs_op_pdaf (for ensemble mean)\n " \ + " 3. py__obs_op_pdaf (for each ensemble member)\n " \ + " 4. core ESTKF algorithm\n " \ + " 8. py__prepoststep_state_pdaf\n " \ + " 9. py__distribute_state_pdaf\n " \ + " 10. py__next_observation_pdaf" +docstrings['omi_assimilate_en3dvar_lestkf'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf`\n "\ + "or :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf_nondiagR`.\n\n "\ + "PDAFlocal-OMI modules require fewer user-supplied\n "\ + "functions and improved efficiency.\n\n " \ + "3DEnVar for a single DA step where the ensemble anomaly\n "\ + "is generated by LESTKF using diagnoal observation\n "\ + "error covariance matrix.\n " \ + "The background error covariance matrix is estimated by ensemble.\n " \ + "The 3DEnVar only calculates the analysis of the ensemble mean.\n " \ + "An LESTKF is used to generate ensemble perturbations.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.omi_put_state_en3dvar_lestkf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. Starting the iterative optimisation:\n " \ + " 1. py__cvt_ens_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__obs_op_adj_pdaf\n " \ + " 4. py__cvt_adj_ens_pdaf\n " \ + " 5. core DA algorithm\n " \ + " 6. py__cvt_ens_pdaf\n " \ + " 7. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n "\ + " (for each ensemble member)\n " \ + " 4. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_state_pdaf\n " \ + " 4. core DA algorithm\n " \ + " 5. py__l2g_state_pdaf\n " \ + " 8. py__prepoststep_state_pdaf\n " \ + " 9. py__distribute_state_pdaf\n " \ + " 10. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf`\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf_nondiagR`" +docstrings['omi_assimilate_hyb3dvar_estkf'] = \ + "Hybrid 3DEnVar for a single DA step\n "\ + "using diagnoal observation error covariance matrix.\n\n "\ + "See :func:`pyPDAF.PDAF.omi_assimilate_hyb3dvar_estkf_nondiagR`\n "\ + "for non-diagonal observation error covariance matrix.\n\n " \ + "Here the background error covariance is hybridised by\n "\ + "a static background error covariance,\n " \ + "and a flow-dependent background error covariance\n "\ + "estimated from ensemble.\n " \ + "The 3DVar generates an ensemble mean and\n "\ + "the ensemble perturbation is generated by\n " \ + "ESTKF in this implementation.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_estkf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. the iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__cvt_ens_pdaf\n " \ + " 3. py__obs_op_lin_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_pdaf\n " \ + " 6. py__cvt_adj_ens_pdaf\n " \ + " 7. core 3DEnVar algorithm\n " \ + " 6. py__cvt_pdaf\n " \ + " 7. py__cvt_ens_pdaf\n " \ + " 8. Perform ESTKF:\n " \ + " 1. py__init_dim_obs_pdaf\n " \ + " 2. py__obs_op_pdaf\n "\ + " (for ensemble mean)\n " \ + " 3. py__obs_op_pdaf\n " \ + " (for each ensemble member)\n " \ + " 4. core ESTKF algorithm\n " \ + " 9. py__prepoststep_state_pdaf\n " \ + " 10. py__distribute_state_pdaf\n " \ + " 11. py__next_observation_pdaf" +docstrings['omi_assimilate_hyb3dvar_lestkf'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf`\n "\ + "or :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf_nondiagR`.\n\n "\ + "PDAFlocal-OMI modules require fewer user-supplied\n "\ + "functions and improved efficiency.\n\n " \ + "Hybrid 3DEnVar for a single DA step\n "\ + "using diagnoal observation error covariance matrix where\n " \ + "the background error covariance is hybridised by\n "\ + "a static background error covariance,\n " \ + "and a flow-dependent background error covariance\n "\ + "estimated from ensemble.\n " \ + "The 3DVar generates an ensemble mean and\n "\ + "the ensemble perturbation is generated by\n " \ + "LESTKF in this implementation.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_lestkf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. The iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__cvt_ens_pdaf\n " \ + " 3. py__obs_op_lin_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_pdaf\n " \ + " 6. py__cvt_adj_ens_pdaf\n " \ + " 7. core DA algorithm\n " \ + " 6. py__cvt_pdaf\n " \ + " 7. py__cvt_ens_pdaf\n " \ + " 8. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n " \ + " (for each ensemble member)\n " \ + " 4. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_state_pdaf\n " \ + " 4. core DA algorithm\n " \ + " 5. py__l2g_state_pdaf\n " \ + " 9. py__prepoststep_state_pdaf\n " \ + " 10. py__distribute_state_pdaf\n " \ + " 11. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf`\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf_nondiagR`" +docstrings['omi_assimilate_global'] = \ + "Global filters except for 3DVar\n "\ + "for a single DA step using diagnoal\n "\ + "observation error covariance matrix.\n\n "\ + "See :func:`pyPDAF.PDAF.omi_assimilate_enkf_nondiagR`, \n " \ + "or :func:`pyPDAF.PDAF.omi_assimilate_global_nondiagR`,\n " \ + "or :func:`pyPDAF.PDAF.omi_assimilate_nonlin_nondiagR`\n "\ + "for non-diagonal observation error covariance matrix.\n\n " \ + "Here, this function call is used for\n "\ + "global stochastic EnKF [1]_, E(S)TKF [2]_, \n " \ + "SEEK [2]_, SEIK [2]_, NETF [3]_, and particle filter [4]_.\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n " \ + "This function should be called at each model time step. \n\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.omi_put_state_global` " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n "\ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for ensemble mean)\n " \ + " 5. py__obs_op_pdaf (for each ensemble member)\n " \ + " 6. core DA algorithm\n " \ + " 7. py__prepoststep_state_pdaf\n " \ + " 8. py__distribute_state_pdaf\n " \ + " 9. py__next_observation_pdaf" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Evensen, G. (1994), \n "\ + " Sequential data assimilation with\n " \ + " a nonlinear quasi-geostrophic model\n "\ + " using Monte Carlo methods to forecast error statistics,\n "\ + " J. Geophys. Res., 99(C5), 10143–10162, doi:10.1029/94JC00572.\n " \ + ".. [2] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345.\n " \ + " doi:10.1175/MWR-D-11-00102.1\n " \ + ".. [3] Tödter, J., and B. Ahrens, 2015:\n "\ + " A second-order exact ensemble square root filter\n " \ + " for nonlinear data assimilation. Mon. Wea. Rev.,\n " \ + " 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1.\n " \ + ".. [4] Van Leeuwen, P. J., Künsch, H. R., Nerger, L.,\n " \ + " Potthast, R., & Reich, S. (2019).\n "\ + " Particle filters for high‐dimensional geoscience applications:\n "\ + " A review. Quarterly Journal of the Royal Meteorological Society, 145(723), 2335-2365." +docstrings['omi_assimilate_lenkf'] = \ + "Covariance localised stochastic EnKF\n " \ + "for a single DA step using diagnoal observation error covariance matrix.\n\n " \ + "See :func:`pyPDAF.PDAF.omi_assimilate_lenkf_nondiagR`\n " \ + "for non-diagnoal observation error covariance matrix.\n\n "\ + "This is the only scheme for covariance localisation in PDAF.\n\n " \ + "The implementation is based on [1]_.\n\n " \ + "This function should be called at each model time step.\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.omi_put_state_lenkf`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for each ensemble member)\n " \ + " 5. py__localize_pdaf\n " \ + " 6. py__obs_op_pdaf (repeated to reduce storage)\n " \ + " 7. core DA algorith\n " \ + " 8. py__prepoststep_state_pdaf\n " \ + " 9. py__distribute_state_pdaf\n " \ + " 10. py__next_observation_pdaf" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Houtekamer, P. L., and H. L. Mitchell (1998): \n " \ + " Data Assimilation Using an Ensemble Kalman Filter Technique.\n "\ + " Mon. Wea. Rev., 126, 796–811,\n "\ + " doi: 10.1175/1520-0493(1998)126<0796:DAUAEK>2.0.CO;2." +docstrings['omi_assimilate_local'] = \ + "It is recommended to use :func:`pyPDAF.PDAF.localomi_assimilate`\n "\ + "or :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`,\n " \ + "or :func:`pyPDAF.PDAF.localomi_assimilate_lnetf_nondiagR`,\n " \ + "or :func:`pyPDAF.PDAF.localomi_assimilate_lknetf_nondiagR`.\n\n " \ + "PDAFlocal-OMI modules require fewer user-supplied\n " \ + "functions and improved efficiency.\n\n " \ + "Domain local filters for a single DA step\n " \ + "using diagnoal observation error covariance matrix.\n " \ + "Here, this function call is used for LE(S)TKF [1]_, \n " \ + "LSEIK [1]_, LNETF [2]_, and LKNETF [3]_.\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n " \ + "This function should be called at each model time step.\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.omi_put_state_local`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__g2l_state_pdaf\n "\ + " 4. core DA algorithm\n " \ + " 5. py__l2g_state_pdaf\n "\ + " 7. py__prepoststep_state_pdaf\n "\ + " 8. py__distribute_state_pdaf\n "\ + " 9. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.localomi_assimilate`\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`,\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_lnetf_nondiagR`,\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_lknetf_nondiagR`." \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345.\n " \ + " doi:10.1175/MWR-D-11-00102.1\n " \ + ".. [2] Tödter, J., and B. Ahrens, 2015:\n "\ + " A second-order exact ensemble square root filter\n " \ + " for nonlinear data assimilation. Mon. Wea. Rev.,\n " \ + " 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1.\n " \ + ".. [3] Nerger, L.. (2022) \n " \ + " Data assimilation for nonlinear systems with\n " \ + " a hybrid nonlinear Kalman ensemble transform filter. \n " \ + " Q J R Meteorol Soc, 620–640. doi:10.1002/qj.4221" +docstrings['omi_generate_obs'] = \ + "Generation of synthetic observations\n " \ + "based on given error statistics and observation operator\n " \ + "for diagonal observation error covariance matrix.\n\n " \ + "If non-diagonal observation error covariance matrix has to be used,\n " \ + "the generic :func:`pyPDAF.PDAF.generate_obs` can be used.\n\n "\ + "The generated synthetic observations are\n " \ + "based on each member of model forecast.\n " \ + "Therefore, an ensemble of observations can\n " \ + "be obtained. In a typical experiment,\n "\ + "one may only need one ensemble member.\n " \ + "The implementation strategy is similar to\n " \ + "an assimilation step. This means that, \n " \ + "one can reuse many user-supplied functions\n " \ + "for assimilation and observation generation.\n\n " \ + "The function is a combination of\n " \ + ":func:`pyPDAF.PDAF.omi_put_state_generate_obs`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n "\ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pda\n " \ + " 5. py__get_obs_f_pdaf\n " \ + " 6. py__prepoststep_state_pdaf\n " \ + " 7. py__distribute_state_pdaf\n " \ + " 8. py__next_observation_pdaf" + +docstrings['omi_assimilate_3dvar_nondiagR'] = \ + "3DVar DA for a single DA step\n "\ + "using non-diagnoal observation error covariance matrix.\n\n "\ + "See :func:`pyPDAF.PDAF.omi_assimilate_3dvar`\n "\ + "for simpler user-supplied functions\n " \ + "using diagonal observation error covariance matrix.\n\n "\ + "When 3DVar is used, the background error covariance matrix\n "\ + "has to be modelled for cotrol variable transformation.\n " \ + "This is a deterministic filtering scheme\n "\ + "so no ensemble and parallelisation is needed.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.omi_put_state_3dvar_nondiagR`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n "\ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. Iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__prodRinvA_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_pdaf\n " \ + " 6. core DA algorithm\n " \ + " 6. py__cvt_pdaf\n " \ + " 7. py__prepoststep_state_pdaf\n " \ + " 8. py__distribute_state_pdaf\n " \ + " 9. py__next_observation_pdaf" +docstrings['omi_assimilate_en3dvar_estkf_nondiagR'] = \ + "3DEnVar for a single DA step\n "\ + "using non-diagnoal observation error covariance matrix.\n\n " \ + "See :func:`pyPDAF.PDAF.omi_assimilate_en3dvar_estkf`\n "\ + "for simpler user-supplied functions\n " \ + "using diagonal observation error covariance matirx.\n\n " \ + "Here, the background error covariance matrix is\n "\ + "estimated by an ensemble.\n " \ + "The 3DEnVar only calculates the analysis of the ensemble mean.\n " \ + "An ESTKF is used along with 3DEnVar to generate ensemble perturbations.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.omi_put_state_en3dvar_estkf_nondiagR`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. the iterative optimisation:\n " \ + " 1. py__cvt_ens_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__prodRinvA_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_ens_pdaf\n " \ + " 6. core 3DEnVar algorithm\n " \ + " 6. py__cvt_ens_pdaf\n " \ + " 7. ESTKF:\n " \ + " 1. py__init_dim_obs_pdaf\n " \ + " 2. py__obs_op_pdaf (for ensemble mean)\n " \ + " 3. py__obs_op_pdaf (for each ensemble member)\n " \ + " 4. py__prodRinvA_pdaf\n " \ + " 5. core ESTKF algorithm\n " \ + " 8. py__prepoststep_state_pdaf\n " \ + " 9. py__distribute_state_pdaf\n " \ + " 10. py__next_observation_pdaf" +docstrings['omi_assimilate_en3dvar_lestkf_nondiagR'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf_nondiagR`\n "\ + "or :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf`.\n\n "\ + "PDAFlocal-OMI modules require fewer user-supplied\n "\ + "functions and improved efficiency.\n\n " \ + "3DEnVar for a single DA step where the ensemble anomaly\n "\ + "is generated by LESTKF\n "\ + "using non-diagnoal observation error covariance matrix.\n " \ + "The background error covariance matrix is estimated by ensemble.\n " \ + "The 3DEnVar only calculates the analysis of the ensemble mean.\n " \ + "An LESTKF is used to generate ensemble perturbations.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.omi_put_state_en3dvar_lestkf_nondiagR`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. Starting the iterative optimisation:\n " \ + " 1. py__cvt_ens_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__prodRinvA_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_ens_pdaf\n " \ + " 6. core DA algorithm\n " \ + " 6. py__cvt_ens_pdaf\n " \ + " 7. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n "\ + " (for each ensemble member)\n " \ + " 4. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_state_pdaf\n " \ + " 4. py__prodRinvA_l_pdaf\n " \ + " 5. core DA algorithm\n " \ + " 6. py__l2g_state_pdaf\n " \ + " 8. py__prepoststep_state_pdaf\n " \ + " 9. py__distribute_state_pdaf\n " \ + " 10. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf`\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_en3dvar_lestkf_nondiagR`" +docstrings['omi_assimilate_hyb3dvar_estkf_nondiagR'] = \ + "Hybrid 3DEnVar for a single DA step\n "\ + "using non-diagnoal observation error covariance matrix.\n\n "\ + "See :func:`pyPDAF.PDAF.omi_assimilate_hyb3dvar_estkf`\n "\ + "for simpler user-supplied functions\n " \ + "using diagonal observation error covariance matrix.\n\n " \ + "Here the background error covariance is hybridised by\n "\ + "a static background error covariance,\n " \ + "and a flow-dependent background error covariance\n "\ + "estimated from ensemble.\n " \ + "The 3DVar generates an ensemble mean and\n "\ + "the ensemble perturbation is generated by\n " \ + "ESTKF in this implementation.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_estkf_nondiagR`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. the iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__cvt_ens_pdaf\n " \ + " 3. py__obs_op_lin_pdaf\n " \ + " 4. py__prodRinvA_pdaf\n " \ + " 5. py__obs_op_adj_pdaf\n " \ + " 6. py__cvt_adj_pdaf\n " \ + " 7. py__cvt_adj_ens_pdaf\n " \ + " 8. core 3DEnVar algorithm\n " \ + " 6. py__cvt_pdaf\n " \ + " 7. py__cvt_ens_pdaf\n " \ + " 8. Perform ESTKF:\n " \ + " 1. py__init_dim_obs_pdaf\n " \ + " 2. py__obs_op_pdaf\n "\ + " (for ensemble mean)\n " \ + " 3. py__obs_op_pdaf\n " \ + " (for each ensemble member)\n " \ + " 4. py__prodRinvA_pdaf\n " \ + " 5. core ESTKF algorithm\n " \ + " 9. py__prepoststep_state_pdaf\n " \ + " 10. py__distribute_state_pdaf\n " \ + " 11. py__next_observation_pdaf" +docstrings['omi_assimilate_hyb3dvar_lestkf_nondiagR'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf_nondiagR`\n "\ + "or :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf`.\n\n "\ + "PDAFlocal-OMI modules require fewer user-supplied functions\n "\ + "and improved efficiency.\n\n " \ + "Hybrid 3DEnVar for a single DA step\n "\ + "using diagnoal observation error covariance matrix where\n " \ + "the background error covariance is hybridised by\n "\ + "a static background error covariance,\n " \ + "and a flow-dependent background error covariance\n "\ + "estimated from ensemble.\n " \ + "The 3DVar generates an ensemble mean and\n "\ + "the ensemble perturbation is generated by\n " \ + "LESTKF in this implementation.\n " \ + "This function should be called at each model time step.\n\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_lestkf_nondiagR`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. The iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__cvt_ens_pdaf\n " \ + " 3. py__obs_op_lin_pdaf\n " \ + " 4. py__prodRinvA_pdaf\n " \ + " 5. py__obs_op_adj_pdaf\n " \ + " 6. py__cvt_adj_pdaf\n " \ + " 7. py__cvt_adj_ens_pdaf\n " \ + " 8. core DA algorithm\n " \ + " 6. py__cvt_pdaf\n " \ + " 7. py__cvt_ens_pdaf\n " \ + " 8. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n " \ + " (for each ensemble member)\n " \ + " 4. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_state_pdaf\n " \ + " 4. py__prodRinvA_l_pdaf\n " \ + " 5. core DA algorithm\n " \ + " 6. py__l2g_state_pdaf\n " \ + " 9. py__prepoststep_state_pdaf\n " \ + " 10. py__distribute_state_pdaf\n " \ + " 11. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf`\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_hyb3dvar_lestkf_nondiagR`" +docstrings['omi_assimilate_enkf_nondiagR'] = \ + "Stochastic EnKF for a single DA step\n "\ + "using non-diagnoal observation error covariance matrix.\n\n " \ + "See :func:`pyPDAF.PDAF.omi_assimilate_global`\n "\ + "for simpler user-supplied functions\n " \ + "using diagonal observation error covariance matrix.\n\n " \ + "The stochastic EnKF is proposed by Evensen [1]_ and\n "\ + "is a Monte Carlo approximation of the KF.\n\n " \ + "This function should be called at each model time step. \n\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.omi_put_state_enkf_nondiagR` " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n "\ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for ensemble mean)\n " \ + " 5. py__add_obs_err_pdaf\n " \ + " 6. py__init_obscovar_pdaf\n " \ + " 7. py__obs_op_pdaf (for each ensemble member)\n " \ + " 8. core DA algorithm\n " \ + " 9. py__prepoststep_state_pdaf\n " \ + " 10. py__distribute_state_pdaf\n " \ + " 11. py__next_observation_pdaf" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Evensen, G. (1994), \n "\ + " Sequential data assimilation with\n "\ + " a nonlinear quasi-geostrophic model\n "\ + " using Monte Carlo methods to forecast error statistics,\n "\ + " J. Geophys. Res., 99(C5), 10143–10162, doi:10.1029/94JC00572." +docstrings['omi_assimilate_global_nondiagR'] = \ + "Global filters except for 3DVar and stochastic EnKF\n "\ + "for a single DA step using non-diagnoal observation\n "\ + "error covariance matrix.\n\n "\ + "See :func:`pyPDAF.PDAF.omi_assimilate_global`\n "\ + "for simpler user-supplied functions\n " \ + "using diagonal observation error covariance matrix.\n\n " \ + "Here, this function call is used for global, E(S)TKF [1]_, \n " \ + "SEEK [1]_, SEIK [1]_.\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n " \ + "This function should be called at each model time step. \n\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.omi_put_state_global` " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n "\ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for ensemble mean)\n " \ + " 5. py__obs_op_pdaf (for each ensemble member)\n " \ + " 6. py__prodRinvA_pdaf\n " \ + " 7. core DA algorithm\n " \ + " 8. py__prepoststep_state_pdaf\n " \ + " 9. py__distribute_state_pdaf\n " \ + " 10. py__next_observation_pdaf" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345.\n "\ + " doi:10.1175/MWR-D-11-00102.1" +docstrings['omi_assimilate_nonlin_nondiagR'] = \ + "Global nonlinear filters for a single DA step\n "\ + "using non-diagnoal observation error covariance matrix.\n\n "\ + "See :func:`pyPDAF.PDAF.omi_assimilate_global_nondiagR`\n "\ + "for simpler user-supplied functions\n " \ + "using diagonal observation error covariance matrix.\n\n " \ + "Here, this function call is used for global NETF [1]_,\n "\ + "and particle filter [2]_.\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n " \ + "This function should be called at each model time step. \n\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.omi_put_state_global_nondiagR` " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n "\ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for ensemble mean)\n " \ + " 5. py__obs_op_pdaf (for each ensemble member)\n " \ + " 6. py__likelihood_pdaf\n " \ + " 7. core DA algorithm\n " \ + " 8. py__prepoststep_state_pdaf\n " \ + " 9. py__distribute_state_pdaf\n " \ + " 10. py__next_observation_pdaf" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Tödter, J., and B. Ahrens, 2015:\n "\ + " A second-order exact ensemble square root filter\n " \ + " for nonlinear data assimilation. Mon. Wea. Rev.,\n " \ + " 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1.\n " \ + ".. [2] Van Leeuwen, P. J., Künsch, H. R., Nerger, L.,\n "\ + " Potthast, R., & Reich, S. (2019).\n "\ + " Particle filters for high‐dimensional geoscience applications:\n "\ + " A review. Quarterly Journal of the Royal Meteorological Society, 145(723), 2335-2365." +docstrings['omi_assimilate_lenkf_nondiagR'] = \ + "Covariance localised stochastic EnKF\n "\ + "for a single DA step using non-diagnoal observation error covariance matrix.\n\n " \ + "See :func:`pyPDAF.PDAF.omi_assimilate_lenkf`\n "\ + "for simpler user-supplied functions\n " \ + "using diagnoal observation error covariance matrix.\n\n "\ + "This stochastic EnKF is implemented based on [1]_\n\n " \ + "This is the only scheme for covariance localisation in PDAF.\n\n " \ + "This function should be called at each model time step.\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.omi_put_state_lenkf_nondiagR`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for each ensemble member)\n " \ + " 5. py__localize_pdaf\n " \ + " 6. py__add_obs_err_pdaf\n " \ + " 7. py__init_obscovar_pdaf\n " \ + " 8. py__obs_op_pdaf (repeated to reduce storage)\n " \ + " 9. core DA algorith\n " \ + " 10. py__prepoststep_state_pdaf\n " \ + " 11. py__distribute_state_pdaf\n " \ + " 12. py__next_observation_pdaf" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Houtekamer, P. L., and H. L. Mitchell (1998): \n " \ + " Data Assimilation Using an Ensemble Kalman Filter Technique.\n "\ + " Mon. Wea. Rev., 126, 796–811,\n "\ + " doi: 10.1175/1520-0493(1998)126<0796:DAUAEK>2.0.CO;2." +docstrings['omi_assimilate_local_nondiagR'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`\n "\ + "or :func:`pyPDAF.PDAF.localomi_assimilate`.\n\n " \ + "PDAFlocal-OMI modules require fewer user-supplied functions\n "\ + "and improved efficiency.\n\n " \ + "Domain local filters for a single DA step\n "\ + "using non-diagnoal observation error covariance matrix.\n " \ + "Here, this function call is used for LE(S)TKF [1]_ and LSEIK [1]_\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n " \ + "This function should be called at each model time step.\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.omi_put_state_local_nondiagR`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__g2l_state_pdaf\n "\ + " 4. py__init_obs_l_pdaf\n "\ + " 5. py__prodRinvA_l_pdaf\n " \ + " 6. core DA algorithm\n " \ + " 7. py__l2g_state_pdaf\n "\ + " 7. py__prepoststep_state_pdaf\n "\ + " 8. py__distribute_state_pdaf\n "\ + " 9. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_assimilate`\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_nondiagR`." \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345.\n "\ + " doi:10.1175/MWR-D-11-00102.1" +docstrings['omi_assimilate_lnetf_nondiagR'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_assimilate_lnetf_nondiagR`\n "\ + "or :func:`pyPDAF.PDAF.localomi_assimilate`.\n\n " \ + "PDAFlocal-OMI modules require fewer user-supplied functions\n "\ + "and improved efficiency.\n\n " \ + "LNETF [1]_ for a single DA step using\n "\ + "non-diagnoal observation error covariance matrix.\n " \ + "See :func:`pyPDAF.PDAF.localomi_assimilate`\n "\ + "for using diagnoal observation error covariance matrix.\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n " \ + "This function should be called at each model time step.\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.omi_put_state_lnetf_nondiagR`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__g2l_state_pdaf\n "\ + " 4. py__likelihood_l_pdaf\n " \ + " 5. core DA algorithm\n " \ + " 6. py__l2g_state_pdaf\n "\ + " 7. py__prepoststep_state_pdaf\n "\ + " 8. py__distribute_state_pdaf\n "\ + " 9. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_assimilate`\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_lnetf_nondiagR`." \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Tödter, J., and B. Ahrens, 2015:\n "\ + " A second-order exact ensemble square root filter\n " \ + " for nonlinear data assimilation. Mon. Wea. Rev.,\n " \ + " 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1." +docstrings['omi_assimilate_lknetf_nondiagR'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_assimilate_lknetf_nondiagR`\n "\ + "or :func:`pyPDAF.PDAF.localomi_assimilate`.\n\n " \ + "PDAFlocal-OMI modules require fewer user-supplied\n "\ + "functions and improved efficiency.\n\n " \ + "LKNETF [1]_ for a single DA step using non-diagnoal\n "\ + "observation error covariance matrix.\n " \ + "See :func:`pyPDAF.PDAF.localomi_assimilate`\n "\ + "for using diagnoal observation error covariance matrix.\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n " \ + "This function should be called at each model time step.\n " \ + "The function is a combination of\n "\ + ":func:`pyPDAF.PDAF.omi_put_state_lknetf_nondiagR`\n " \ + "and :func:`pyPDAF.PDAF.get_state`.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__g2l_state_pdaf\n "\ + " 4. py__prodRinvA_pdaf\n " \ + " 5. py__likelihood_l_pdaf\n " \ + " 6. core DA algorithm\n " \ + " 7. py__l2g_state_pdaf\n "\ + " 8. py__obs_op_pdaf\n " \ + " (only called with `HKN` and `HNK` options\n "\ + " called for each ensemble member)\n " \ + " 9. py__likelihood_hyb_l_pda\n " \ + " 10. py__prodRinvA_hyb_l_pdaf\n " \ + " 7. py__prepoststep_state_pdaf\n "\ + " 8. py__distribute_state_pdaf\n "\ + " 9. py__next_observation_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_assimilate`\n " \ + " and :func:`pyPDAF.PDAF.localomi_assimilate_lnetf_nondiagR`." \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L.. (2022) \n " \ + " Data assimilation for nonlinear systems with\n "\ + " a hybrid nonlinear Kalman ensemble transform filter. \n " \ + " Q J R Meteorol Soc, 620–640. doi:10.1002/qj.4221" diff --git a/pyPDAF/source/tool/docstring/pdafomi_put_state_docstrings.py b/pyPDAF/source/tool/docstring/pdafomi_put_state_docstrings.py new file mode 100644 index 0000000000000000000000000000000000000000..ac994b88ebbcf07d9f31cae1bc04f1714b312245 --- /dev/null +++ b/pyPDAF/source/tool/docstring/pdafomi_put_state_docstrings.py @@ -0,0 +1,1016 @@ +"""docstrings for PDAFomi_assimilate_xxx functions +""" +docstrings = {} + +docstrings['omi_put_state_3dvar'] = \ + "3DVar DA for a single DA step\n "\ + "using diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n "\ + "and setting next observation step.\n\n " \ + "See :func:`pyPDAF.PDAF.omi_put_state_3dvar_nondiagR`\n "\ + "for non-diagonal observation error covariance matrix.\n\n "\ + "Compared to :func:`pyPDAF.PDAF.omi_assimilate_3dvar`,\n "\ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n "\ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n "\ + "not be assigned by user-supplied functions as well.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "When 3DVar is used, the background error covariance matrix\n "\ + "has to be modelled for cotrol variable transformation.\n " \ + "This is a deterministic filtering scheme\n "\ + "so no ensemble and parallelisation is needed.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. Iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__obs_op_adj_pdaf\n " \ + " 4. py__cvt_adj_pdaf\n " \ + " 5. core DA algorithm\n " \ + " 6. py__cvt_pdaf" +docstrings['omi_put_state_en3dvar_estkf'] = \ + "3DEnVar for a single DA step\n "\ + "using diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n "\ + "and setting next observation step.\n\n " \ + "See :func:`pyPDAF.PDAF.omi_put_state_en3dvar_estkf_nondiagR`\n "\ + "for non-diagonal observation error covariance matrix.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.omi_assimilate_en3dvar_estkf`,\n "\ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n "\ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n "\ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n "\ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n "\ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The background error covariance matrix is\n "\ + "estimated by an ensemble.\n " \ + "The 3DEnVar only calculates the analysis of\n "\ + "the ensemble mean.\n " \ + "An ESTKF is used along with 3DEnVar to\n "\ + "generate ensemble perturbations.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. the iterative optimisation:\n " \ + " 1. py__cvt_ens_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__obs_op_adj_pdaf\n " \ + " 4. py__cvt_adj_ens_pdaf\n " \ + " 5. core 3DEnVar algorithm\n " \ + " 6. py__cvt_ens_pdaf\n " \ + " 7. ESTKF:\n " \ + " 1. py__init_dim_obs_pdaf\n " \ + " 2. py__obs_op_pdaf (for ensemble mean)\n " \ + " 3. py__obs_op_pdaf (for each ensemble member)\n " \ + " 4. core ESTKF algorithm" +docstrings['omi_put_state_en3dvar_lestkf'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf_nondiagR`.\n\n "\ + "PDAFlocal-OMI modules require fewer user-supplied\n "\ + "functions and improved efficiency.\n\n " \ + "3DEnVar for a single DA step where the ensemble anomaly\n "\ + "is generated by LESTKF using diagnoal observation\n "\ + "error covariance matrix.\n\n " \ + "Compared to\n "\ + ":func:`pyPDAF.PDAF.omi_assimilate_en3dvar_lestkf`,\n "\ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n "\ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n "\ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n "\ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n "\ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The background error covariance matrix is\n "\ + "estimated by ensemble.\n " \ + "The 3DEnVar only calculates the analysis of the ensemble mean.\n " \ + "An LESTKF is used to generate ensemble perturbations.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. Starting the iterative optimisation:\n " \ + " 1. py__cvt_ens_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__obs_op_adj_pdaf\n " \ + " 4. py__cvt_adj_ens_pdaf\n " \ + " 5. core DA algorithm\n " \ + " 6. py__cvt_ens_pdaf\n " \ + " 7. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n "\ + " (for each ensemble member)\n " \ + " 4. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_state_pdaf\n " \ + " 4. core DA algorithm\n " \ + " 5. py__l2g_state_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf_nondiagR`" +docstrings['omi_put_state_hyb3dvar_estkf'] = \ + "Hybrid 3DEnVar for a single DA step\n "\ + "using diagnoal observation error covariance matrix\n "\ + "without post-processing, distributing analysis,\n "\ + "and setting next observation step.\n\n " \ + "See :func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_estkf_nondiagR`\n "\ + "for non-diagonal observation error covariance matrix.\n\n " \ + "Hybrid 3DEnVar for a single DA step where\n " \ + "the background error covariance is hybridised by\n "\ + "a static background error covariance,\n " \ + "and a flow-dependent background error covariance\n "\ + "estimated from ensemble.\n\n " \ + "Compared to\n "\ + ":func:`pyPDAF.PDAF.omi_assimilate_hyb3dvar_estkf`,\n "\ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n "\ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n "\ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n "\ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n "\ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The 3DVar generates an ensemble mean and\n "\ + "the ensemble perturbation is generated by\n " \ + "ESTKF in this implementation.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. the iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__cvt_ens_pdaf\n " \ + " 3. py__obs_op_lin_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_pdaf\n " \ + " 6. py__cvt_adj_ens_pdaf\n " \ + " 7. core 3DEnVar algorithm\n " \ + " 6. py__cvt_pdaf\n " \ + " 7. py__cvt_ens_pdaf\n " \ + " 8. Perform ESTKF:\n " \ + " 1. py__init_dim_obs_pdaf\n " \ + " 2. py__obs_op_pdaf\n "\ + " (for ensemble mean)\n " \ + " 3. py__obs_op_pdaf\n " \ + " (for each ensemble member)\n " \ + " 4. core ESTKF algorithm\n" +docstrings['omi_put_state_hyb3dvar_lestkf'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf_nondiagR`.\n\n "\ + "PDAFlocal-OMI modules require fewer user-supplied\n "\ + "functions and improved efficiency.\n\n " \ + "Hybrid 3DEnVar for a single DA step using\n "\ + "diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n "\ + "and setting next observation step, where\n " \ + "the background error covariance is hybridised by\n "\ + "a static background error covariance,\n " \ + "and a flow-dependent background error covariance\n "\ + "estimated from ensemble.\n\n " \ + "Compared to\n "\ + ":func:`pyPDAF.PDAF.omi_assimilate_hyb3dvar_lestkf`,\n "\ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n "\ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n "\ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n "\ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n "\ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The 3DVar generates an ensemble mean and\n "\ + "the ensemble perturbation is generated by\n " \ + "LESTKF in this implementation.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. The iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__cvt_ens_pdaf\n " \ + " 3. py__obs_op_lin_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_pdaf\n " \ + " 6. py__cvt_adj_ens_pdaf\n " \ + " 7. core DA algorithm\n " \ + " 6. py__cvt_pdaf\n " \ + " 7. py__cvt_ens_pdaf\n " \ + " 8. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n " \ + " (for each ensemble member)\n " \ + " 4. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_state_pdaf\n " \ + " 4. core DA algorithm\n " \ + " 5. py__l2g_state_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf_nondiagR`" +docstrings['omi_put_state_global'] = \ + "Global filters except for 3DVar for\n "\ + "a single DA step using diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n "\ + "and setting next observation step.\n\n " \ + "See :func:`pyPDAF.PDAF.omi_put_state_enkf_nondiagR`, \n " \ + "or :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR`,\n " \ + "or :func:`pyPDAF.PDAF.omi_put_state_nonlin_nondiagR`\n "\ + "for non-diagonal observation error covariance matrix.\n\n " \ + "OMI functions need fewer user-supplied functions and\n "\ + "improve DA efficiency.\n\n " \ + "Here, this function call is used for\n "\ + "global stochastic EnKF [1]_, E(S)TKF [2]_, \n " \ + "SEEK [2]_, SEIK [2]_, NETF [3]_, and particle filter [4]_.\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n " \ + "Compared to :func:`pyPDAF.PDAF.omi_assimilate_global`,\n "\ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n "\ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n "\ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n "\ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n "\ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The ESTKF is a more efficient equivalent to the ETKF.\n\n " \ + "The function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for ensemble mean)\n " \ + " 5. py__init_obs_pdaf\n " \ + " 6. py__obs_op_pdaf (for each ensemble member)\n " \ + " 7. py__init_obsvar_pdaf (only relevant for\n "\ + " adaptive forgetting factor schemes)\n " \ + " 8. py__prodRinvA_pdaf\n " \ + " 9. core DA algorithm\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n "\ + " :func:`pyPDAF.PDAF.omi_put_state_global`\n " \ + " and :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR`." \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Evensen, G. (1994), \n "\ + " Sequential data assimilation with\n "\ + " a nonlinear quasi-geostrophic model\n "\ + " using Monte Carlo methods to forecast error statistics,\n "\ + " J. Geophys. Res., 99(C5), 10143–10162, doi:10.1029/94JC00572.\n " \ + ".. [2] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345.\n "\ + " doi:10.1175/MWR-D-11-00102.1\n " \ + ".. [3] Tödter, J., and B. Ahrens, 2015:\n "\ + " A second-order exact ensemble square root filter\n " \ + " for nonlinear data assimilation. Mon. Wea. Rev.,\n " \ + " 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1.\n " \ + ".. [4] Van Leeuwen, P. J., Künsch, H. R., Nerger, L.,\n "\ + " Potthast, R., & Reich, S. (2019).\n "\ + " Particle filters for high‐dimensional geoscience applications:\n "\ + " A review. Quarterly Journal of the\n "\ + " Royal Meteorological Society, 145(723), 2335-2365." +docstrings['omi_put_state_lenkf'] = \ + "Stochastic EnKF (ensemble Kalman filter)\n "\ + "with covariance localisation using diagnoal observation\n "\ + "error covariance matrix\n "\ + "without post-processing, distributing analysis,\n "\ + "and setting next observation step.\n\n " \ + "See :func:`pyPDAF.PDAF.omi_put_state_lenkf_nondiagR`\n "\ + "for non-diagonal observation error covariance matrix.\n\n "\ + "Stochastic EnKF (ensemble Kalman filter) with covariance localisation [1]_\n " \ + "for a single DA step.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.omi_assimilate_lenkf`,\n "\ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n "\ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n "\ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n "\ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n "\ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "This is the only scheme for covariance localisation in PDAF.\n\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for each ensemble member)\n " \ + " 5. py__localize_pdaf\n " \ + " 6. py__obs_op_pdaf (repeated to reduce storage)\n " \ + " 7. core DA algorith" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Houtekamer, P. L., and H. L. Mitchell (1998): \n " \ + " Data Assimilation Using an Ensemble Kalman Filter Technique.\n "\ + " Mon. Wea. Rev., 126, 796–811,\n "\ + " doi: 10.1175/1520-0493(1998)126<0796:DAUAEK>2.0.CO;2." +docstrings['omi_put_state_local'] = \ + "It is recommended to use\n "\ + ":func:`pyPDAF.PDAF.localomi_put_state`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`,\n " \ + "or :func:`pyPDAF.PDAF.localomi_put_state_lnetf_nondiagR`,\n " \ + "or :func:`pyPDAF.PDAF.localomi_put_state_lknetf_nondiagR`.\n\n " \ + "PDAFlocal-OMI modules require fewer user-supplied\n "\ + "functions and improved efficiency.\n\n " \ + "Domain local filters for a single DA step using\n "\ + "diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n "\ + "and setting next observation step.\n\n " \ + "Here, this function call is used for LE(S)TKF [1]_, \n " \ + "LSEIK [1]_, LNETF [2]_, and LKNETF [3]_.\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n " \ + "Compared to :func:`pyPDAF.PDAF.omi_assimilate_local`,\n "\ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n "\ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n "\ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n "\ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n "\ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The LESTKF is a more efficient equivalent to the LETKF.\n\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__g2l_state_pdaf\n "\ + " 4. core DA algorithm\n " \ + " 5. py__l2g_state_pdaf\n"\ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by :func:`pyPDAF.PDAF.omi_put_state`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`,\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_lnetf_nondiagR`,\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_lknetf_nondiagR`." \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345.\n "\ + " doi:10.1175/MWR-D-11-00102.1\n " \ + ".. [2] Tödter, J., and B. Ahrens, 2015:\n "\ + " A second-order exact ensemble square root filter\n " \ + " for nonlinear data assimilation. Mon. Wea. Rev.,\n " \ + " 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1.\n " \ + ".. [3] Nerger, L.. (2022) \n " \ + " Data assimilation for nonlinear systems with\n "\ + " a hybrid nonlinear Kalman ensemble transform filter. \n " \ + " Q J R Meteorol Soc, 620–640. doi:10.1002/qj.4221" +docstrings['omi_put_state_generate_obs'] = \ + "Generation of synthetic observations\n "\ + "based on given error statistics and\n "\ + "observation operator for diagonal observation\n "\ + "error covariance matrix\n " \ + "without post-processing, distributing analysis,\n "\ + "and setting next observation step.\n\n " \ + "If non-diagonal observation error covariance matrix has to be used,\n " \ + "the generic :func:`pyPDAF.PDAF.put_generate_obs` can be used.\n\n "\ + "The generated synthetic observations are\n "\ + "based on each member of model forecast.\n " \ + "Therefore, an ensemble of observations can be obtained.\n "\ + "In a typical experiment,\n "\ + "one may only need one ensemble member.\n\n " \ + "Compared to :func:`pyPDAF.PDAF.omi_generate_obs`,\n "\ + "this function has no :func:`get_state` call.\n " \ + "This means that the next DA step will\n "\ + "not be assigned by user-supplied functions.\n " \ + "This function is typically used when there are\n "\ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n "\ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The implementation strategy is similar to\n "\ + "an assimilation step. This means that, \n " \ + "one can reuse many user-supplied functions\n "\ + "for assimilation and observation generation.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pda\n " \ + " 5. py__get_obs_f_pdaf" + +docstrings['omi_put_state_3dvar_nondiagR'] = \ + "3DVar DA for a single DA step\n " \ + "using non-diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n " \ + "and setting next observation step.\n\n " \ + "See :func:`pyPDAF.PDAF.omi_put_state_3dvar`\n " \ + "for simpler user-supplied functions using\n " \ + "diagonal observation error covariance matrix.\n\n "\ + "Compared to\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_3dvar_nondiagR`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions.\n " \ + "The next DA step will not be assigned\n " \ + "by user-supplied functions as well.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "When 3DVar is used, the background error covariance matrix\n "\ + "has to be modelled for cotrol variable transformation.\n " \ + "This is a deterministic filtering scheme\n " \ + "so no ensemble and parallelisation is needed.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. Iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__prodRinvA_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_pdaf\n " \ + " 6. core DA algorithm\n " \ + " 6. py__cvt_pdaf" +docstrings['omi_put_state_en3dvar_estkf_nondiagR'] = \ + "3DEnVar for a single DA step\n " \ + "using non-diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n " \ + "and setting next observation step.\n\n " \ + "See :func:`pyPDAF.PDAF.omi_put_state_en3dvar_estkf`\n " \ + "for simpler user-supplied functions\n " \ + "using diagonal observation error covariance matrix.\n\n " \ + "Compared to\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_en3dvar_estkf_nondiagR`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The background error covariance matrix is\n " \ + "estimated by an ensemble.\n " \ + "The 3DEnVar only calculates the analysis of the ensemble mean.\n " \ + "An ESTKF is used along with 3DEnVar to generate ensemble perturbations.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. the iterative optimisation:\n " \ + " 1. py__cvt_ens_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__prodRinvA_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_ens_pdaf\n " \ + " 6. core 3DEnVar algorithm\n " \ + " 6. py__cvt_ens_pdaf\n " \ + " 7. ESTKF:\n " \ + " 1. py__init_dim_obs_pdaf\n " \ + " 2. py__obs_op_pdaf (for ensemble mean)\n " \ + " 3. py__obs_op_pdaf (for each ensemble member)\n " \ + " 4. py__prodRinvA_pdaf\n " \ + " 5. core ESTKF algorithm" +docstrings['omi_put_state_en3dvar_lestkf_nondiagR'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf_nondiagR`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf`.\n\n "\ + "PDAFlocal-OMI modules require fewer user-supplied\n " \ + "functions and improved efficiency.\n\n " \ + "3DEnVar for a single DA step without post-processing,\n " \ + "distributing analysis, and setting next observation step,\n "\ + "where the ensemble anomaly is generated by LESTKF\n " \ + "using non-diagnoal observation error covariance matrix.\n\n " \ + "Compared to\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_en3dvar_lestkf_nondiagR`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The background error covariance matrix is\n " \ + "estimated by ensemble.\n " \ + "The 3DEnVar only calculates the analysis of the ensemble mean.\n " \ + "An LESTKF is used to generate ensemble perturbations.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. Starting the iterative optimisation:\n " \ + " 1. py__cvt_ens_pdaf\n " \ + " 2. py__obs_op_lin_pdaf\n " \ + " 3. py__prodRinvA_pdaf\n " \ + " 4. py__obs_op_adj_pdaf\n " \ + " 5. py__cvt_adj_ens_pdaf\n " \ + " 6. core DA algorithm\n " \ + " 6. py__cvt_ens_pdaf\n " \ + " 7. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n "\ + " (for each ensemble member)\n " \ + " 4. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_state_pdaf\n " \ + " 4. py__prodRinvA_l_pdaf\n " \ + " 5. core DA algorithm\n " \ + " 6. py__l2g_state_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf_nondiagR`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_en3dvar_lestkf`" +docstrings['omi_put_state_hyb3dvar_estkf_nondiagR'] = \ + "Hybrid 3DEnVar for a single DA step\n " \ + "using non-diagnoal observation error covariance matrix\n "\ + "without post-processing, distributing analysis,\n " \ + "and setting next observation step.\n\n " \ + "See :func:`pyPDAF.PDAF.omi_put_state_hyb3dvar_estkf`\n " \ + "for simpler user-supplied functions\n " \ + "using diagonal observation error covariance matrix.\n\n " \ + "Here the background error covariance is hybridised by\n " \ + "a static background error covariance,\n " \ + "and a flow-dependent background error covariance\n " \ + "estimated from ensemble.\n\n " \ + "Compared to\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_hyb3dvar_estkf_nondiagR`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The 3DVar generates an ensemble mean and\n " \ + "the ensemble perturbation is generated by\n " \ + "ESTKF in this implementation.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. the iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__cvt_ens_pdaf\n " \ + " 3. py__obs_op_lin_pdaf\n " \ + " 4. py__prodRinvA_pdaf\n " \ + " 5. py__obs_op_adj_pdaf\n " \ + " 6. py__cvt_adj_pdaf\n " \ + " 7. py__cvt_adj_ens_pdaf\n " \ + " 8. core 3DEnVar algorithm\n " \ + " 6. py__cvt_pdaf\n " \ + " 7. py__cvt_ens_pdaf\n " \ + " 8. Perform ESTKF:\n " \ + " 1. py__init_dim_obs_pdaf\n " \ + " 2. py__obs_op_pdaf\n "\ + " (for ensemble mean)\n " \ + " 3. py__obs_op_pdaf\n " \ + " (for each ensemble member)\n " \ + " 4. py__prodRinvA_pdaf\n " \ + " 5. core ESTKF algorithm" +docstrings['omi_put_state_hyb3dvar_lestkf_nondiagR'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf_nondiagR`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf`.\n\n "\ + "PDAFlocal-OMI modules require fewer user-supplied\n " \ + "functions and improved efficiency.\n\n " \ + "Hybrid 3DEnVar for a single DA step\n " \ + "using non-diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n " \ + "and setting next observation step, where\n " \ + "the background error covariance is hybridised by\n " \ + "a static background error covariance,\n " \ + "and a flow-dependent background error covariance\n " \ + "estimated from ensemble.\n\n " \ + "Compared to\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_hyb3dvar_lestkf_nondiagR`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "The 3DVar generates an ensemble mean and\n " \ + "the ensemble perturbation is generated by\n " \ + "LESTKF in this implementation.\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf\n " \ + " 5. The iterative optimisation:\n " \ + " 1. py__cvt_pdaf\n " \ + " 2. py__cvt_ens_pdaf\n " \ + " 3. py__obs_op_lin_pdaf\n " \ + " 4. py__prodRinvA_pdaf\n " \ + " 5. py__obs_op_adj_pdaf\n " \ + " 6. py__cvt_adj_pdaf\n " \ + " 7. py__cvt_adj_ens_pdaf\n " \ + " 8. core DA algorithm\n " \ + " 6. py__cvt_pdaf\n " \ + " 7. py__cvt_ens_pdaf\n " \ + " 8. Perform LESTKF:\n " \ + " 1. py__init_n_domains_p_pdaf\n " \ + " 2. py__init_dim_obs_pdaf\n " \ + " 3. py__obs_op_pdaf\n " \ + " (for each ensemble member)\n " \ + " 4. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n " \ + " 2. py__init_dim_obs_l_pdaf\n " \ + " 3. py__g2l_state_pdaf\n " \ + " 4. py__prodRinvA_l_pdaf\n " \ + " 5. core DA algorithm\n " \ + " 6. py__l2g_state_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_hyb3dvar_lestkf_nondiagR`" +docstrings['omi_put_state_enkf_nondiagR'] = \ + "Stochastic EnKF for a single DA step\n " \ + "using non-diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n " \ + "and setting next observation step.\n\n " \ + "See :func:`pyPDAF.PDAF.omi_put_state_global`\n " \ + "for simpler user-supplied functions\n " \ + "using diagonal observation error covariance matrix.\n\n " \ + "The stochastic EnKF is implemented based on [1]_.\n\n " \ + "Compared to\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_enkf_nondiagR`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "This function should be called at each model time step. \n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for ensemble mean)\n " \ + " 5. py__add_obs_err_pdaf\n " \ + " 6. py__init_obscovar_pdaf\n " \ + " 7. py__obs_op_pdaf (for each ensemble member)\n " \ + " 8. core DA algorithm" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Evensen, G. (1994), \n "\ + " Sequential data assimilation with\n " \ + " a nonlinear quasi-geostrophic model\n "\ + " using Monte Carlo methods to forecast error statistics,\n "\ + " J. Geophys. Res., 99(C5), 10143–10162, doi:10.1029/94JC00572." +docstrings['omi_put_state_global_nondiagR'] = \ + "Global filters except for 3DVar and stochastic EnKF\n " \ + "for a single DA step using non-diagnoal observation\n " \ + "error covariance matrix\n "\ + "without post-processing, distributing analysis,\n " \ + "and setting next observation step.\n\n " \ + "See :func:`pyPDAF.PDAF.omi_put_state_global`\n " \ + "for simpler user-supplied functions\n " \ + "using diagonal observation error covariance matrix.\n\n " \ + "Here, this function call is used for global, E(S)TKF [1]_, \n " \ + "SEEK [1]_, SEIK [1]_.\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n\n " \ + "Compared to\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_global_nondiagR`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "This function should be called at each model time step. \n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for ensemble mean)\n " \ + " 5. py__obs_op_pdaf (for each ensemble member)\n " \ + " 6. py__prodRinvA_pdaf\n " \ + " 7. core DA algorithm" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345.\n " \ + " doi:10.1175/MWR-D-11-00102.1" +docstrings['omi_put_state_nonlin_nondiagR'] = \ + "Global nonlinear filters for a single DA step\n " \ + "using non-diagnoal observation error covariance matrix\n "\ + "without post-processing, distributing analysis,\n " \ + "and setting next observation step.\n\n " \ + "See :func:`pyPDAF.PDAF.omi_put_state_global_nondiagR`\n " \ + "for simpler user-supplied functions\n " \ + "using diagonal observation error covariance matrix.\n\n " \ + "Here, this function call is used for global NETF [1]_,\n " \ + "and particle filter [2]_.\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n\n " \ + "Compared to\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_nonlin_nondiagR`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "This function should be called at each model time step. \n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for ensemble mean)\n " \ + " 5. py__obs_op_pdaf (for each ensemble member)\n " \ + " 6. py__likelihood_pdaf\n " \ + " 7. core DA algorithm" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Tödter, J., and B. Ahrens, 2015:\n "\ + " A second-order exact ensemble square root filter\n " \ + " for nonlinear data assimilation. Mon. Wea. Rev.,\n " \ + " 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1.\n " \ + ".. [2] Van Leeuwen, P. J., Künsch, H. R., Nerger, L.,\n " \ + " Potthast, R., & Reich, S. (2019).\n "\ + " Particle filters for high‐dimensional geoscience applications:\n "\ + " A review.\n " \ + " Quarterly Journal of the Royal Meteorological Society,\n " \ + " 145(723), 2335-2365." +docstrings['omi_put_state_lenkf_nondiagR'] = \ + "Covariance localised stochastic EnKF\n " \ + "for a single DA step using non-diagnoal observation\n " \ + "error covariance matrix\n "\ + "without post-processing, distributing analysis,\n " \ + "and setting next observation step.\n\n " \ + "See :func:`pyPDAF.PDAF.omi_put_state_lenkf`\n " \ + "for simpler user-supplied functions\n " \ + "using diagnoal observation error covariance matrix.\n\n "\ + "This function is implemented based on [1]_.\n\n " \ + "This is the only scheme for covariance localisation in PDAF.\n\n " \ + "Compared to\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_lenkf_nondiagR`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n " \ + " 2. py__prepoststep_state_pdaf\n " \ + " 3. py__init_dim_obs_pdaf\n " \ + " 4. py__obs_op_pdaf (for each ensemble member)\n " \ + " 5. py__localize_pdaf\n " \ + " 6. py__add_obs_err_pdaf\n " \ + " 7. py__init_obscovar_pdaf\n " \ + " 8. py__obs_op_pdaf (repeated to reduce storage)\n " \ + " 9. core DA algorithm" \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Houtekamer, P. L., and H. L. Mitchell (1998): \n " \ + " Data Assimilation Using an Ensemble Kalman Filter Technique.\n "\ + " Mon. Wea. Rev., 126, 796–811,\n "\ + " doi: 10.1175/1520-0493(1998)126<0796:DAUAEK>2.0.CO;2." +docstrings['omi_put_state_local_nondiagR'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.localomi_put_state_nondiagR`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state`.\n\n " \ + "PDAFlocal-OMI modules require fewer user-supplied\n " \ + "functions and improved efficiency.\n\n " \ + "Domain local filters for a single DA step\n " \ + "using non-diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n " \ + "and setting next observation step.\n\n " \ + "Here, this function call is used for LE(S)TKF [1]_ and LSEIK [1]_\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n\n " \ + "Compared to\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_local_nondiagR`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__g2l_state_pdaf\n "\ + " 4. py__init_obs_l_pdaf\n "\ + " 5. py__prodRinvA_l_pdaf\n " \ + " 6. core DA algorithm\n " \ + " 7. py__l2g_state_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.localomi_put_state`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_nondiagR`." \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L., Janjić, T., Schröter, J., Hiller, W. (2012). \n " \ + " A unification of ensemble square root Kalman filters. \n " \ + " Monthly Weather Review, 140, 2335-2345. doi:10.1175/MWR-D-11-00102.1" +docstrings['omi_put_state_lnetf_nondiagR'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.localomi_put_state_lnetf_nondiagR`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state`.\n\n " \ + "PDAFlocal-OMI modules require fewer user-supplied\n " \ + "functions and improved efficiency.\n\n " \ + "LNETF [1]_ for a single DA step\n " \ + "using non-diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n " \ + "and setting next observation step.\n\n " \ + "See :func:`pyPDAF.PDAF.localomi_put_state`\n " \ + "for using diagnoal observation error covariance matrix.\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n\n " \ + "Compared to\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_lnetf_nondiagR`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__g2l_state_pdaf\n "\ + " 4. py__likelihood_l_pdaf\n " \ + " 5. core DA algorithm\n " \ + " 6. py__l2g_state_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.localomi_put_state`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_lnetf_nondiagR`." \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Tödter, J., and B. Ahrens, 2015:\n "\ + " A second-order exact ensemble square root filter\n " \ + " for nonlinear data assimilation. Mon. Wea. Rev.,\n " \ + " 143, 1347–1367, doi:10.1175/MWR-D-14-00108.1." +docstrings['omi_put_state_lknetf_nondiagR'] = \ + "It is recommended to use\n " \ + ":func:`pyPDAF.PDAF.localomi_put_state_lknetf_nondiagR`\n "\ + "or :func:`pyPDAF.PDAF.localomi_put_state`.\n\n " \ + "PDAFlocal-OMI modules require fewer user-supplied\n " \ + "functions and improved efficiency.\n\n " \ + "LKNETF [1]_ for a single DA step using\n " \ + "non-diagnoal observation error covariance matrix\n " \ + "without post-processing, distributing analysis,\n " \ + "and setting next observation step.\n\n " \ + "See :func:`pyPDAF.PDAF.localomi_assimilate`\n " \ + "for using diagnoal observation error covariance matrix.\n " \ + "The filter type is set in :func:`pyPDAF.PDAF.init`.\n\n " \ + "Compared to\n " \ + ":func:`pyPDAF.PDAF.omi_assimilate_lknetf_nondiagR`,\n " \ + "this function has no :func:`get_state` call.\n " \ + "This means that the analysis is not post-processed,\n " \ + "and distributed to the model forecast\n " \ + "by user-supplied functions. The next DA step will\n " \ + "not be assigned by user-supplied functions as well.\n " \ + "This function is typically used when there are\n " \ + "not enough CPUs to run the ensemble in parallel,\n "\ + "and some ensemble members have to be run serially.\n " \ + "The :func:`pyPDAF.PDAF.get_state` function follows this\n "\ + "function call to ensure the sequential DA.\n\n " \ + "This function should be called at each model time step.\n\n " \ + "User-supplied functions are executed in the following sequence:\n " \ + " 1. py__collect_state_pdaf\n "\ + " 2. py__prepoststep_state_pdaf\n "\ + " 3. py__init_n_domains_p_pdaf\n "\ + " 4. py__init_dim_obs_pdaf\n "\ + " 5. py__obs_op_pdaf (for each ensemble member)\n "\ + " 6. loop over each local domain:\n " \ + " 1. py__init_dim_l_pdaf\n "\ + " 2. py__init_dim_obs_l_pdaf\n "\ + " 3. py__g2l_state_pdaf\n "\ + " 4. py__prodRinvA_pdaf\n " \ + " 5. py__likelihood_l_pdaf\n " \ + " 6. core DA algorithm\n " \ + " 7. py__l2g_state_pdaf\n "\ + " 8. py__obs_op_pdaf\n " \ + " (only called with `HKN` and `HNK` options\n " \ + " called for each ensemble member)\n " \ + " 9. py__likelihood_hyb_l_pda\n " \ + " 10. py__prodRinvA_hyb_l_pdaf\n" \ + "\n " \ + ".. deprecated:: 1.0.0\n\n " \ + " This function is replaced by\n " \ + " :func:`pyPDAF.PDAF.localomi_put_state`\n " \ + " and :func:`pyPDAF.PDAF.localomi_put_state_lnetf_nondiagR`." \ + "\n\n " \ + "References\n " \ + "----------\n " \ + ".. [1] Nerger, L.. (2022) \n " \ + " Data assimilation for nonlinear systems with\n " \ + " a hybrid nonlinear Kalman ensemble transform filter.\n " \ + " Q J R Meteorol Soc, 620–640. doi:10.1002/qj.4221" diff --git a/pyPDAF/source/tool/get_decls.py b/pyPDAF/source/tool/get_decls.py new file mode 100644 index 0000000000000000000000000000000000000000..149770f5b20cacef35299de4b1693e5560d6dda1 --- /dev/null +++ b/pyPDAF/source/tool/get_decls.py @@ -0,0 +1,226 @@ +import re +from pathlib import Path +import textwrap + + +WRAP_WIDTH = 80 +TYPE_MAP = { + 'integer': ('INTEGER', 'c_int'), + 'real': ('REAL', 'c_double'), + 'logical': ('LOGICAL', 'c_bool'), + 'complex': ('COMPLEX', 'c_double_complex'), + 'character': ('CHARACTER', 'c_char') +} + +def extract_dimension_shape(decl_code: str) -> str: + # Find the DIMENSION keyword + match = re.search(r'dimension\s*\(', decl_code, re.IGNORECASE) + if not match: + return "" + + start = match.end() # position after '(' + depth = 1 + i = start + while i < len(decl_code): + if decl_code[i] == '(': + depth += 1 + elif decl_code[i] == ')': + depth -= 1 + if depth == 0: + return decl_code[start:i].strip() + i += 1 + return "" # if unmatched + +def split_outside_parens(s: str): + """ + Split s on commas that are not enclosed in parentheses. + E.g. "a(:,:), b, c(:)" → ["a(:,:)", " b", " c(:)"] + """ + parts = [] + buf = "" + depth = 0 + for ch in s: + if ch == "(": + depth += 1 + buf += ch + elif ch == ")": + depth -= 1 + buf += ch + elif ch == "," and depth == 0: + parts.append(buf) + buf = "" + else: + buf += ch + if buf: + parts.append(buf) + return parts + + +def _process_buffer(buffer, buffer_comments, arg_names, decls, comments): + """ + Helper: split `buffer` on '::', then split RHS on commas outside parens, + match to arg_names, record decl_code and join buffer_comments into one. + """ + try: + left, right = buffer.split("::", 1) + except ValueError: + return + + decl_code = left.strip().lower() + var_list = right.strip() + if len(buffer_comments) == 0: + buffer_comments = ["" for _ in split_outside_parens(var_list)] + + for chunk in split_outside_parens(var_list): + name_with_shape = chunk.strip() + # match base name + optional shape + m = re.match(r'(\w+)\s*(\([^\)]*\))?', name_with_shape) + if not m: + continue + base = m.group(1).lower() + # m = re.search(r'dimension\s*\(([^)]+)\)', decl_code, re.IGNORECASE) + # shape = m.group(1) if m else "" + shape = extract_dimension_shape(decl_code) + if base in arg_names: + decls.append((base, decl_code, shape)) + comments[base] = buffer_comments + + +def extract_subroutine_blocks(lines): + """ + Return a list of [start_line_idx, end_line_idx, block_lines] for each + SUBROUTINE … END SUBROUTINE found **outside** any INTERFACE / ABSTRACT INTERFACE. + """ + blocks = [] + interface_depth = 0 + i = 0 + n = len(lines) + + while i < n: + line = lines[i] + + # Entering an INTERFACE or ABSTRACT INTERFACE + if re.match(r'\s*(abstract\s+)?interface\b', line, re.I): + interface_depth += 1 + i += 1 + continue + + # Leaving an INTERFACE block + if re.match(r'\s*end\s+interface\b', line, re.I): + if interface_depth > 0: + interface_depth -= 1 + i += 1 + continue + + # Only consider SUBROUTINE if we're *not* inside an interface + if interface_depth == 0 and re.match(r'\s*subroutine\s+', line, re.I): + start = i + # find the matching END SUBROUTINE + i += 1 + while i < n and not re.match(r'\s*end\s+subroutine\b', lines[i], re.I): + i += 1 + # include the END SUBROUTINE line + if i < n: + end = i + blocks.append(lines[start:end+1]) + i += 1 + continue + + i += 1 + + return blocks + + +def extract_multiline_signature(block): + sig_lines = [] + inside = False + start_idx = None + for idx, line in enumerate(block): + if not inside and re.match(r'\s*subroutine\s+', line, re.I): + inside = True + start_idx = idx + if inside: + sig_lines.append(line.strip()) + if ")" in line: + break + if not sig_lines: + raise ValueError("No subroutine signature found") + + # Join and clean + full_sig = " ".join(sig_lines).replace("&", "") + match = re.match(r'\s*subroutine\s+(\w+)\s*\(([^)]*)\)', full_sig, re.I) + if not match: + raise ValueError(f"Could not parse subroutine signature from:\n{full_sig}") + + name = match.group(1) + args = [x.strip().lower() for x in match.group(2).split(',') if x.strip()] + return name, args, start_idx + + +def extract_declarations_by_args(block, start_idx, arg_names): + """ + From block[start_idx:] find all “::” declarations, including + multi-line EXTERNAL/PROCEDURE and type declarations. + Returns: + decls = [(var_name, decl_code), …] + comments = { var_name: comment_str, … } + """ + decls = [] + comments = {} + + buffer = "" # holds the code part across continuations + buffer_comments = [] # list of comment fragments + + for line in block[start_idx:]: + # stop at end of subroutine + if re.match(r'\s*end\s+subroutine', line, re.I): + break + + if 'implicit none' in line: + continue + + + raw = line.rstrip("\n") + # 1) split off any comment + if "!" in raw: + code_part, comment_part = raw.split("!", 1) + else: + code_part, comment_part = raw, None + + if 'use ' in code_part.lower(): + continue + + # --- Start a new declaration if we see '::' and we're not in one --- + if comment_part and buffer_comments == []: + buffer_comments = [comment_part.strip()] + comment_part = "" + + if not buffer and "::" in code_part: + buffer = code_part.strip() + # single-line decl: process immediately + _process_buffer(buffer, buffer_comments, arg_names, decls, comments) + buffer = "" + buffer_comments = [] + continue + + if not buffer and code_part.strip() == "": + if comment_part: + buffer_comments.append(comment_part.strip()) + continue + + return decls, comments + + +def compare_signature_and_declarations(arg_list, decls): + """ + Given: + arg_list : ['u_collect_state', 'u_obs_op', 'u_init_obs', ...] + decls : [('u_collect_state', 'external'), ('u_obs_op', 'external'), ...] + Returns: + missing : [ names in arg_list but not in decls ] + extra : [ names in decls but not in arg_list ] + """ + decl_vars = {var for var, _, _ in decls} + missing = [arg for arg in arg_list if arg not in decl_vars] + extra = [var for var, _, _ in decls if var not in arg_list] + return missing, extra diff --git a/pyPDAF/source/tool/get_decls_cb.py b/pyPDAF/source/tool/get_decls_cb.py new file mode 100644 index 0000000000000000000000000000000000000000..be5e26646dd87cd8df17bc1b5c705ee5338e52a7 --- /dev/null +++ b/pyPDAF/source/tool/get_decls_cb.py @@ -0,0 +1,258 @@ +import re +from pathlib import Path +import textwrap + + +WRAP_WIDTH = 80 +TYPE_MAP = { + 'integer': ('INTEGER', 'c_int'), + 'real': ('REAL', 'c_double'), + 'logical': ('LOGICAL', 'c_bool'), + 'complex': ('COMPLEX', 'c_double_complex'), + 'character': ('CHARACTER', 'c_char') +} + + +def split_outside_parens(s: str): + """ + Split s on commas that are not enclosed in parentheses. + E.g. "a(:,:), b, c(:)" → ["a(:,:)", " b", " c(:)"] + """ + parts = [] + buf = "" + depth = 0 + for ch in s: + if ch == "(": + depth += 1 + buf += ch + elif ch == ")": + depth -= 1 + buf += ch + elif ch == "," and depth == 0: + parts.append(buf) + buf = "" + else: + buf += ch + if buf: + parts.append(buf) + return parts + + +def _process_buffer(buffer, buffer_comments, arg_names, decls, comments): + """ + Helper: split `buffer` on '::', then split RHS on commas outside parens, + match to arg_names, record decl_code and join buffer_comments into one. + """ + try: + left, right = buffer.split("::", 1) + except ValueError: + return + + decl_code = left.strip().lower() + var_list = right.strip() + if len(buffer_comments) == 0: + buffer_comments = ["" for _ in split_outside_parens(var_list)] + + for chunk in split_outside_parens(var_list): + name_with_shape = chunk.strip() + # match base name + optional shape + m = re.match(r'(\w+)\s*(\([^\)]*\))?', name_with_shape) + if not m: + continue + base = m.group(1).lower() + m = re.search(r'dimension\s*\(([^)]+)\)', decl_code, re.IGNORECASE) + shape = m.group(1) if m else "" + if base in arg_names: + decls.append((base, decl_code, shape)) + comments[base] = buffer_comments + + +def extract_subroutine_blocks(lines): + """ + Return a list of [start_line_idx, end_line_idx, block_lines] for each + SUBROUTINE … END SUBROUTINE found **outside** any INTERFACE / ABSTRACT INTERFACE. + """ + blocks = [] + interface_depth = 0 + i = 0 + n = len(lines) + + while i < n: + line = lines[i] + + # Only consider SUBROUTINE if we're *not* inside an interface + if interface_depth == 0 and re.match(r'\s*subroutine\s+', line, re.I): + start = i + # find the matching END SUBROUTINE + i += 1 + while i < n and not re.match(r'\s*end\s+subroutine\b', lines[i], re.I): + i += 1 + # include the END SUBROUTINE line + if i < n: + end = i + blocks.append(lines[start:end+1]) + i += 1 + continue + + i += 1 + + return blocks + + +def extract_multiline_signature(block): + sig_lines = [] + inside = False + start_idx = None + for idx, line in enumerate(block): + if not inside and re.match(r'\s*subroutine\s+', line, re.I): + inside = True + start_idx = idx + if inside: + sig_lines.append(line.strip()) + if ")" in line: + break + if not sig_lines: + raise ValueError("No subroutine signature found") + + # Join and clean + full_sig = " ".join(sig_lines).replace("&", "") + match = re.match(r'\s*subroutine\s+(\w+)\s*\(([^)]*)\)', full_sig, re.I) + if not match: + raise ValueError(f"Could not parse subroutine signature from:\n{full_sig}") + + name = match.group(1) + args = [x.strip().lower() for x in match.group(2).split(',') if x.strip()] + return name, args, start_idx + + +def extract_declarations_by_args(block, start_idx, arg_names): + """ + From block[start_idx:] find all “::” declarations, including + multi-line EXTERNAL/PROCEDURE and type declarations. + Returns: + decls = [(var_name, decl_code), …] + comments = { var_name: comment_str, … } + """ + decls = [] + comments = {} + + buffer = "" # holds the code part across continuations + buffer_comments = [] # list of comment fragments + + collecting = False + for line in block[start_idx:]: + # only start after IMPLICIT NONE + if not collecting: + if re.match(r'\s*implicit\s+none', line, re.I): + collecting = True + continue + + # stop at end of subroutine + if re.match(r'\s*end\s+subroutine', line, re.I): + break + + raw = line.rstrip("\n") + # 1) split off any comment + if "!" in raw: + code_part, comment_part = raw.split("!", 1) + else: + code_part, comment_part = raw, None + + # --- Start a new declaration if we see '::' and we're not in one --- + if comment_part and buffer_comments == []: + buffer_comments = [comment_part.strip()] + comment_part = "" + + if not buffer and "::" in code_part: + buffer = code_part.strip() + # if this line ends with '&', stay in continuation + if buffer.strip().endswith("&"): + continuing_decl = True + buffer = buffer.rstrip("&").rstrip() + else: + continuing_decl = False + # single-line decl: process immediately + _process_buffer(buffer, buffer_comments, arg_names, decls, comments) + buffer = "" + buffer_comments = [] + continue + + if not buffer and code_part.strip() == "": + if comment_part: + buffer_comments.append( comment_part.strip() ) + continue + return decls, comments + + +def compare_signature_and_declarations(arg_list, decls): + """ + Given: + arg_list : ['u_collect_state', 'u_obs_op', 'u_init_obs', ...] + decls : [('u_collect_state', 'external'), ('u_obs_op', 'external'), ...] + Returns: + missing : [ names in arg_list but not in decls ] + extra : [ names in decls but not in arg_list ] + """ + decl_vars = {var for var, _, _ in decls} + missing = [arg for arg in arg_list if arg not in decl_vars] + extra = [var for var, _, _ in decls if var not in arg_list] + return missing, extra + + +def get_pyx_arg(arg_list, decl_map): + pyx_in_arg_list = [] + pyx_out_arg_list = [] + for arg in arg_list: + code, _ = decl_map.get(arg, ("", "")) + match = re.search(r'intent\(in\)|intent\(inout\)', code, re.IGNORECASE) + if match: + pyx_in_arg_list.append(arg) + match = re.search(r'intent\(out\)|intent\(inout\)', code, re.IGNORECASE) + if match: + pyx_out_arg_list.append(arg) + return pyx_in_arg_list, pyx_out_arg_list + + +def get_c_def(src_dir): + filepath = Path(src_dir) / Path('pdaf_c_cb_interface.f90') + with open(filepath, 'r') as f: + lines = f.readlines() + + blocks = extract_subroutine_blocks(lines) + + if not blocks: + print (f"No subroutines found in {filepath}") + return # No subroutines, skip + + cb_interface = {} + for block in blocks: + # try: + name, arg_list, start_idx = extract_multiline_signature(block) + decls, comments = extract_declarations_by_args(block, start_idx, arg_list) + missing, extra = compare_signature_and_declarations(arg_list, decls) + if missing: + print(f"!!! Missing declarations for: {missing} in {name} in {filepath}") + if extra: + print(f"!!! Declared but not in signature: {extra} in {name} in {filepath}") + + name = name.lower() + cb_interface[name] = { + 'args': arg_list, + 'decls': decls, + 'comments': comments + } + # except Exception as e: + # print(f"Skipping block in {filepath}: {e}") + + return cb_interface + + +def get_pyx_def(src_dir): + cb_interface = get_c_def(src_dir) + for proc in cb_interface: + decls_map = {var: (code, shape) for var, code, shape in cb_interface[proc]['decls']} + pyx_in_args, pyx_out_args = get_pyx_arg(cb_interface[proc]['args'], decls_map) + cb_interface[proc]['pyx_in_args'] = pyx_in_args + cb_interface[proc]['pyx_out_args'] = pyx_out_args + return cb_interface + diff --git a/pyPDAF/source/tool/write_binding.py b/pyPDAF/source/tool/write_binding.py new file mode 100644 index 0000000000000000000000000000000000000000..f90464f5bfa5d20c46810b1c6145605ff5884a76 --- /dev/null +++ b/pyPDAF/source/tool/write_binding.py @@ -0,0 +1,459 @@ +import re +from pathlib import Path +import textwrap + + +WRAP_WIDTH = 80 +TYPE_MAP = { + 'integer': ('INTEGER', 'c_int'), + 'real': ('REAL', 'c_double'), + 'logical': ('LOGICAL', 'c_bool'), + 'complex': ('COMPLEX', 'c_double_complex'), + 'character': ('CHARACTER', 'c_char') +} + + +def split_outside_parens(s: str): + """ + Split s on commas that are not enclosed in parentheses. + E.g. "a(:,:), b, c(:)" → ["a(:,:)", " b", " c(:)"] + """ + parts = [] + buf = "" + depth = 0 + for ch in s: + if ch == "(": + depth += 1 + buf += ch + elif ch == ")": + depth -= 1 + buf += ch + elif ch == "," and depth == 0: + parts.append(buf) + buf = "" + else: + buf += ch + if buf: + parts.append(buf) + return parts + + +def _process_buffer(buffer, buffer_comments, arg_names, decls, comments): + """ + Helper: split `buffer` on '::', then split RHS on commas outside parens, + match to arg_names, record decl_code and join buffer_comments into one. + """ + try: + left, right = buffer.split("::", 1) + except ValueError: + return + + decl_code = left.strip().lower() + var_list = right.strip() + if len(buffer_comments) == 0: + buffer_comments = ["" for _ in split_outside_parens(var_list)] + + for chunk, comment in zip(split_outside_parens(var_list), buffer_comments): + name_with_shape = chunk.strip() + # match base name + optional shape + m = re.match(r'(\w+)\s*(\([^\)]*\))?', name_with_shape) + if not m: + continue + base = m.group(1).lower() + shape = m.group(2) or "" + if base in arg_names: + decls.append((base, decl_code, shape)) + if comment: + comments[base] = comment + + +def wrap_comma_list(prefix, items, subsequent_indent=" ", suffix=""): + """ + Wrap a comma-separated list under WRAP_WIDTH, inserting '&' + at end of every line except the last, and appending `suffix` + (e.g. ' bind(c)') to that last line. + """ + lines = [] + current = prefix + for i, item in enumerate(items): + sep = ", " if i < len(items) - 1 else ")" + addition = item + sep + # if adding this would exceed limit (allowing space for ' &' on wrapped lines) + if len(current) + len(addition) + (3 if sep==", " else len(suffix)) > WRAP_WIDTH: + lines.append(current + " &") + current = subsequent_indent + item + sep + else: + current += addition + # if items were empty, we might have just the prefix + if current == prefix: + current += ")" + + # append suffix to the final line + if suffix: + current = current + suffix + lines.append(current) + return lines + + +def extract_subroutine_blocks(lines): + """ + Return a list of [start_line_idx, end_line_idx, block_lines] for each + SUBROUTINE … END SUBROUTINE found **outside** any INTERFACE / ABSTRACT INTERFACE. + """ + blocks = [] + interface_depth = 0 + i = 0 + n = len(lines) + + while i < n: + line = lines[i] + + # Entering an INTERFACE or ABSTRACT INTERFACE + if re.match(r'\s*(abstract\s+)?interface\b', line, re.I): + interface_depth += 1 + i += 1 + continue + + # Leaving an INTERFACE block + if re.match(r'\s*end\s+interface\b', line, re.I): + if interface_depth > 0: + interface_depth -= 1 + i += 1 + continue + + # Only consider SUBROUTINE if we're *not* inside an interface + if interface_depth == 0 and re.match(r'\s*subroutine\s+', line, re.I): + start = i + # find the matching END SUBROUTINE + i += 1 + while i < n and not re.match(r'\s*end\s+subroutine\b', lines[i], re.I): + i += 1 + # include the END SUBROUTINE line + if i < n: + end = i + blocks.append(lines[start:end+1]) + i += 1 + continue + + i += 1 + + return blocks + + +def extract_multiline_signature(block): + sig_lines = [] + inside = False + start_idx = None + for idx, line in enumerate(block): + if not inside and re.match(r'\s*subroutine\s+', line, re.I): + inside = True + start_idx = idx + if inside: + sig_lines.append(line.strip()) + if ")" in line: + break + if not sig_lines: + raise ValueError("No subroutine signature found") + + # Join and clean + full_sig = " ".join(sig_lines).replace("&", "") + match = re.match(r'\s*subroutine\s+(\w+)\s*\(([^)]*)\)', full_sig, re.I) + if not match: + raise ValueError(f"Could not parse subroutine signature from:\n{full_sig}") + + name = match.group(1) + args = [x.strip().lower() for x in match.group(2).split(',') if x.strip()] + return name, args, start_idx + + +def extract_declarations_by_args(block, start_idx, arg_names): + """ + From block[start_idx:] find all “::” declarations, including + multi-line EXTERNAL/PROCEDURE and type declarations. + Returns: + decls = [(var_name, decl_code), …] + comments = { var_name: comment_str, … } + """ + decls = [] + comments = {} + + buffer = "" # holds the code part across continuations + buffer_comments = [] # list of comment fragments + + collecting = False + for line in block[start_idx:]: + # only start after IMPLICIT NONE + if not collecting: + if re.match(r'\s*implicit\s+none', line, re.I): + collecting = True + continue + + # stop at end of subroutine + if re.match(r'\s*end\s+subroutine', line, re.I): + break + + raw = line.rstrip("\n") + # 1) split off any comment + if "!" in raw: + code_part, comment_part = raw.split("!", 1) + comment_part = comment_part.replace("<", "", 1).strip() + else: + code_part, comment_part = raw, None + + # --- Start a new declaration if we see '::' and we're not in one --- + if not buffer and "::" in code_part: + buffer = code_part.strip() + if comment_part: + buffer_comments = [comment_part] + else: + buffer_comments = [] + # if this line ends with '&', stay in continuation + if buffer.strip().endswith("&"): + continuing_decl = True + buffer = buffer.rstrip("&").rstrip() + else: + continuing_decl = False + # single-line decl: process immediately + _process_buffer(buffer, buffer_comments, arg_names, decls, comments) + buffer = "" + buffer_comments = [] + continue + + # --- If we're in a continuation, absorb blank/comment lines too --- + if buffer and continuing_decl: + # If there's no code at all, just collect comment and keep going + if code_part.strip() == "": + if comment_part: + buffer_comments[-1] = buffer_comments[-1] + comment_part + continue + + # Otherwise, append code & comment + buffer += " " + code_part.strip() + if comment_part: + buffer_comments.append(comment_part) + + # Still continuing? + if buffer.strip().endswith("&"): + continuing_decl = True + buffer = buffer.rstrip("&").rstrip() + continue + else: + continuing_decl = False + # now we've got the full multi-line decl + _process_buffer(buffer, buffer_comments, arg_names, decls, comments) + buffer = "" + buffer_comments = [] + continue + + return decls, comments + + +def compare_signature_and_declarations(arg_list, decls): + """ + Given: + arg_list : ['u_collect_state', 'u_obs_op', 'u_init_obs', ...] + decls : [('u_collect_state', 'external'), ('u_obs_op', 'external'), ...] + Returns: + missing : [ names in arg_list but not in decls ] + extra : [ names in decls but not in arg_list ] + """ + decl_vars = {var for var, _, _ in decls} + missing = [arg for arg in arg_list if arg not in decl_vars] + extra = [var for var, _, _ in decls if var not in arg_list] + return missing, extra + + +def generate_bindc_wrapper(name, arg_list, decls, comments): + """ + name : original subroutine name (string) + arg_list : list of argument names in order, already lowercased + decls : list of (var, decl_code) from extract_declarations_by_args + comments : dict var->comment_str + """ + wrapper_name = f"c__{name}" + + # detect obs_f / obs_l arguments + obs_args = [ + var for var, code, _ in decls + if re.match(r"type\s*\(\s*obs_f\s*\)", code, re.I) + or re.match(r"type\s*\(\s*obs_l\s*\)", code, re.I) + ] + + # All other args stay in the C-interface + non_obs = [ + v for v in arg_list + if v not in obs_args + ] + + # Build the C-binding argument list: + c_args = [] + if obs_args: + c_args.append("i_obs") + c_args = c_args + non_obs + + # Wrap signature with continuations and bind(c) + sig_lines = wrap_comma_list( + prefix=f"SUBROUTINE c__{name}(", + items=c_args, + subsequent_indent=" ", + suffix=" bind(c)" + ) + + lines = [] + lines.extend(sig_lines) + + if len(c_args) > 0: + lines.append(" use iso_c_binding") + lines.append("") + + # categorize args + typed_args = [] + external_args = [] + decl_map = { var: (code, shape) for var, code, shape in decls } + + # declare i_obs if needed + if obs_args: + lines.append(" ! index into observation arrays") + lines.append(" INTEGER(c_int), INTENT(in) :: i_obs") + lines.append("") + + for var in non_obs: + code, _ = decl_map.get(var, "") + if code.startswith("external") or "procedure" in code: + external_args.append(var) + else: + typed_args.append(var) + + # emit typed args + for var in typed_args: + code, shape = decl_map[var] + # figure out fortran base type → (F_TYPE, C_KIND) + base_type = re.match(r'(integer|real|logical|complex|character)', code).group(1).lower() + f_type, c_kind = TYPE_MAP[base_type] + # pointer if it has 'pointer' in the code + pointer = ", POINTER" if "pointer" in code.lower() else "" + # preserve shape if present + shape_attr = f", DIMENSION{shape}" if shape else "" + # keep intent + intent = re.search(r'intent\s*\(\s*(in|out|inout)\s*\)', code, re.I) + intent_str = f", INTENT({intent.group(1).lower()})" if intent else "" + # comment + if comments.get(var): + lines.append(f" ! {comments[var]}") + else: + lines.append(f" !") + lines.append(f" {f_type}({c_kind}){pointer}{shape_attr}{intent_str} :: {var}") + lines.append("") + + # emit procedure args + for var in external_args: + # comment + if comments.get(var): + lines.append(f" ! {comments[var]}") + else: + lines.append(f" !") + proc_type = f"c__{var}_pdaf" + lines.append(f" procedure({proc_type}) :: {var}") + lines.append("") + + # build the CALL to the original: + call_args = [] + for v in arg_list: + if v in obs_args: + call_args.append(f"{v}(i_obs)") + else: + call_args.append(v) + + call_lines = wrap_comma_list( + f" call {name}(", + call_args, + subsequent_indent=" " + ) + lines.extend(call_lines) + # 8) end + lines.append(f"END SUBROUTINE {wrapper_name}") + lines.append("") # blank after call + + return "\n".join(lines) + + +def process_file(filepath, output_dir): + with open(filepath, 'r') as f: + lines = f.readlines() + + blocks = extract_subroutine_blocks(lines) + + if not blocks: + print (f"No subroutines found in {filepath}") + return # No subroutines, skip + + for block in blocks: + try: + name, arg_list, start_idx = extract_multiline_signature(block) + decls, comments = extract_declarations_by_args(block, start_idx, arg_list) + missing, extra = compare_signature_and_declarations(arg_list, decls) + if missing: + print(f"!!! Missing declarations for: {missing} in {name} in {filepath}") + if extra: + print(f"!!! Declared but not in signature: {extra} in {name} in {filepath}") + # print (decls) + wrapper = generate_bindc_wrapper(name, arg_list, decls, comments) + + if 'pdafomi_assim' in name.lower(): + output_path = Path(output_dir) / 'pdafomi_assim_c_binding.f90' + elif 'pdafomi_put' in name.lower(): + output_path = Path(output_dir) / 'pdafomi_put_c_binding.f90' + elif '_cb' in name.lower(): + output_path = Path(output_dir) / 'pdaf_callback_c_binding.f90' + elif 'pdafomi_set' in name.lower(): + output_path = Path(output_dir) / 'pdafomi_set_c_binding.f90' + elif 'pdafomi' in name.lower(): + output_path = Path(output_dir) / 'pdafomi_c_binding.f90' + elif 'pdaflocalomi_assim' in name.lower(): + output_path = Path(output_dir) / 'pdaflocalomi_assim_c_binding.f90' + elif 'pdaflocalomi_put' in name.lower(): + output_path = Path(output_dir) / 'pdaflocalomi_put_c_binding.f90' + elif 'pdaflocalomi' in name.lower(): + output_path = Path(output_dir) / 'pdaflocalomi_c_binding.f90' + elif 'pdaflocal_assim' in name.lower(): + output_path = Path(output_dir) / 'pdaflocal_assim_c_binding.f90' + elif 'pdaflocal_put' in name.lower(): + output_path = Path(output_dir) / 'pdaflocal_put_c_binding.f90' + elif 'pdaflocal' in name.lower(): + output_path = Path(output_dir) / 'pdaflocal_c_binding.f90' + elif 'pdaf_set' in name.lower(): + output_path = Path(output_dir) / 'pdaf_set_c_binding.f90' + elif 'pdaf_get' in name.lower(): + output_path = Path(output_dir) / 'pdaf_get_c_binding.f90' + elif 'pdaf_assim' in name.lower(): + output_path = Path(output_dir) / 'pdaf_assim_c_binding.f90' + elif 'pdaf_put' in name.lower(): + output_path = Path(output_dir) / 'pdaf_put_c_binding.f90' + elif 'pdaf_diag' in name.lower(): + output_path = Path(output_dir) / 'pdaf_diag_c_binding.f90' + elif 'pdaf_iau' in name.lower(): + output_path = Path(output_dir) / 'pdaf_iau_c_binding.f90' + elif 'pdaf3_assim' in name.lower(): + output_path = Path(output_dir) / 'pdaf3_assim_c_binding.f90' + elif 'pdaf3_put' in name.lower(): + output_path = Path(output_dir) / 'pdaf3_put_c_binding.f90' + else: + output_path = Path(output_dir) / f"pdaf_c_binding.f90" + output_path.parent.mkdir(parents=True, exist_ok=True) + with open(output_path, 'a') as f: + f.write(wrapper + "\n") + except Exception as e: + print(f"Skipping block in {filepath}: {e}") + + +def process_directory(src_dir, dst_dir): + for path in Path(src_dir).rglob("*"): + if path.suffix.lower() in (".f90", ".f", ".f95", ".f03", ".f08", ".for", ".ftn"): + if path.name.lower() in ('pdaf_cb_procedures.f90', 'pdaf_assim_interfaces.f90', + 'pdaf_mod_core.f90', 'pdafomi.f90', 'pdaf.f90'): + continue + process_file(path, dst_dir) + + +if __name__ == "__main__": + process_directory('PDAF-PDAF_V3.0beta/src', 'bindc_files') diff --git a/pyPDAF/source/tool/write_cb_pxd.py b/pyPDAF/source/tool/write_cb_pxd.py new file mode 100644 index 0000000000000000000000000000000000000000..2f0e04911ebca28e9871cfb1a6432f0002f2fe25 --- /dev/null +++ b/pyPDAF/source/tool/write_cb_pxd.py @@ -0,0 +1,88 @@ +import re +from pathlib import Path +import get_decls +import get_decls_cb + +WRAP_WIDTH = 80 + +TYPE_MAP = { + 'integer': 'int* ', + 'real': 'double* ', + 'logical': 'bint* ', + 'character': 'char* ' +} + +def wrap_comma_list(prefix, arg_list, decl_map, subsequent_indent=" ", suffix=""): + """ + Wrap a comma-separated list under WRAP_WIDTH, inserting '&' + at end of every line except the last, and appending `suffix` + (e.g. ' bind(c)') to that last line. + """ + lines = [] + current = prefix + for i, arg in enumerate(arg_list): + sep = ", " if i < len(arg_list) - 1 else ")" + + code, _ = decl_map.get(arg, ("", "")) + if 'pointer' in code or 'dimension(:' in code.lower(): + addition = f'CFI_cdesc_t* ' + arg.lower() + sep + else: + base_type = re.match(r'(integer|real|logical|character)', code).group(1).lower() + c_type = TYPE_MAP[base_type] + addition = c_type + arg.lower() + sep + + # if adding this would exceed limit (allowing space for ' &' on wrapped lines) + if len(current) + len(addition) + (4 if sep==", " else len(suffix)) > WRAP_WIDTH: + lines.append(current) + current = subsequent_indent + addition + else: + current += addition + + # if items were empty, we might have just the prefix + if current == prefix: + current += ")" + + # append suffix to the final line + if suffix: + current = current + suffix + lines.append(current) + return lines + + +def generate_extern_pxd(name, arg_list, decls): + """ + name : original subroutine name (string) + arg_list : list of argument names in order, already lowercased + decls : list of (var, decl_code) from extract_declarations_by_args + comments : dict var->comment_str + """ + decl_map = { var: (code, shape) for var, code, shape in decls } + lines = wrap_comma_list( + prefix=f"cdef void {name.lower()}(", + arg_list=arg_list, + decl_map=decl_map, + suffix=" noexcept nogil;" + ) + lines.append(f"cdef void* {name[3:].lower()} = NULL;") + lines.append("") + return "\n".join(lines) + +def process_file(src_dir, dst_dir): + + cb_interface = get_decls_cb.get_c_def(src_dir) + + for name in cb_interface: + cb_decls = generate_extern_pxd(name, arg_list=cb_interface[name]['args'], + decls=cb_interface[name]['decls']) + filename = 'pdaf_c_cb_interface.pxd' + output_path = Path(dst_dir) / filename + output_path.parent.mkdir(parents=True, exist_ok=True) + with open(output_path, 'a') as f: + f.write(cb_decls + "\n") + + # except Exception as e: + # print(f"Skipping block in {filepath}: {e}") + +if __name__ == "__main__": + # process_directory('/home/users/ia923171/pyPDAF_dev/pyPDAF/src/fortran', '') + process_file('/home/users/ia923171/pyPDAF_dev/pyPDAF/src/fortran', '/home/users/ia923171/pyPDAF_dev/pyPDAF/src/pyPDAF') diff --git a/pyPDAF/source/tool/write_cb_pyx.py b/pyPDAF/source/tool/write_cb_pyx.py new file mode 100644 index 0000000000000000000000000000000000000000..2b2f39d2f70850ee84d8e8690f9e2b0ad04460b4 --- /dev/null +++ b/pyPDAF/source/tool/write_cb_pyx.py @@ -0,0 +1,319 @@ +import math +import re +from pathlib import Path + +import numpy as np +import get_decls +import get_decls_cb +from docstring import docstrings + + +WRAP_WIDTH = 80 + +TYPE_MAP = { + 'integer': 'int', + 'real': 'double', + 'logical': 'bint', + 'character': 'str' +} + +TYPE_MAP_ARR = { + 'integer': 'np.intc', + 'real': 'np.float64', + 'logical': 'np.bool', + 'character': 'np.str_' +} + +TYPE_MAP_CNP = { + 'integer': 'cnp.int32_t', + 'real': 'cnp.float64_t', +} + + + +DUMMY_DOC = "Checking the corresponding PDAF documentation in https://pdaf.awi.de\n" \ + " For internal subroutines checking corresponding PDAF comments." + + +def write_header(): + lines = [] + lines.append("import sys") + lines.append("import numpy as np") + lines.append("import warnings") + + return lines + + +def get_pyx_arg(arg_list, decl_map): + pyx_in_arg_list = [] + pyx_out_arg_list = [] + for arg in arg_list: + code, _ = decl_map.get(arg, ("", "")) + match = re.search(r'procedure\((.*?)\)', code) + if match: + proc_type = match.group(1).lower() + pyx_in_arg_list.append(proc_type.replace("c__", "py__")) + else: + match = re.search(r'intent\(in\)|intent\(inout\)', code, re.IGNORECASE) + if match: + pyx_in_arg_list.append(arg) + match = re.search(r'intent\(out\)|intent\(inout\)', code, re.IGNORECASE) + if match: + pyx_out_arg_list.append(arg) + return pyx_in_arg_list, pyx_out_arg_list + + +def wrap_comma_list(prefix, items, subsequent_indent=" ", suffix=""): + """ + Wrap a comma-separated list under WRAP_WIDTH, inserting '&' + at end of every line except the last, and appending `suffix` + (e.g. ' bind(c)') to that last line. + """ + lines = [] + current = prefix + for i, item in enumerate(items): + sep = ", " if i < len(items) - 1 else ")" + addition = item + sep + # if adding this would exceed limit (allowing space for ' &' on wrapped lines) + if len(current) + len(addition) + (4 if sep==", " else len(suffix)) > WRAP_WIDTH: + lines.append(current) + current = subsequent_indent + item + sep + else: + current += addition + # if items were empty, we might have just the prefix + if current == prefix: + current += ")" + + # append suffix to the final line + if suffix: + current = current + suffix + lines.append(current) + return lines + + +def write_c_signature(pyx_name, arg_list, decl_map): + pyx_def_arg_list = [] + for arg in arg_list: + code, _ = decl_map.get(arg, ("", "")) + if 'dimension(:' in code.lower(): + pyx_def_arg_list.append(f'CFI_cdesc_t* {arg}') + else: + base_type = re.match(r'(integer|real|logical|character)', code).group(1).lower() + pyx_def_arg_list.append(f'{TYPE_MAP[base_type]}* {arg}') + + return wrap_comma_list( + prefix=f"cdef void {pyx_name}(", + items=pyx_def_arg_list, + suffix=" noexcept with gil:" + ) + + +def write_memory_view(arg_list, decl_map, indent=" "): + """Convert 2D arrays to fortran contiguous arrays + """ + + def repl(m: re.Match) -> str: + ident, offset = m.groups() + return f'{ident}[0]{offset}' + # convert np arrays to memoryview + lines = [] + for arg in arg_list: + code, shape = decl_map.get(arg, ("", "")) + if 'dimension' not in code.lower(): + # not a Fortran array, skip + continue + + if 'dimension(:' in code.lower(): + n_dim = len(shape.split(',')) + s = f'cdef CFI_index_t {arg}_subscripts[{n_dim}]' + s = f'cdef size_t {arg}_dim[{n_dim}]' + lines.append(indent + s) + for i in range(n_dim): + s = f'{arg}_subscripts[{i}] = 0' + lines.append(indent + s) + s = f'{arg}_dim[{i}] = {arg}.dim[{i}].extent' + lines.append(indent + s) + + s = f'cdef double *{arg}_ptr = <{TYPE_MAP[base_type]} *>CFI_address({arg}, {arg}_subscripts)' + lines.append(indent + s) + s_colons = ':,' * (n_dim - 1) + s_colons = "::1" if n_dim == 1 else \ + "::1," + s_colons[:-1] # remove last comma + s = f'cdef {TYPE_MAP[base_type]}[{s_colons}] {arg}_np = ' + n_colons = len(shape.split(',')) + s_colons = [f':{arg}_dim[0]:1,', ] + [f':{arg}_dim[{i}]' for i in range(1, n_colons)] + s_colons = ",".join(s_colons) # remove last comma + s += f'np.asarray(<{TYPE_MAP[base_type]}[{s_colons}]> {arg}_ptr, order="F")' + lines.append(indent + s) + + else: + colons = shape.split(',') + n_colons = len(colons) + s_colons = ':,' * (n_colons - 1) + s_colons = "::1" if n_colons == 1 else \ + "::1," + s_colons[:-1] # remove last comma + base_type = re.match(r'(integer|real|logical|character)', code).group(1).lower() + s = f'cdef {TYPE_MAP[base_type]}[{s_colons}] ' + s_colons = [] + for i in range(n_colons): + pat = re.compile(r'\b([A-Za-z_]\w*)'r'(\s*(?:[+-]\s*\d+)?)') + s_col = ':' + pat.sub(repl, colons[i].strip()) + s_col = s_col + ':1' if i == 0 else s_col + s_colons.append(s_col) + s_colons = ",".join(s_colons) # remove last comma + s += f'{arg}_np = np.asarray(<{TYPE_MAP[base_type]}[{s_colons}]> {arg}, order="F")' + lines.append(indent + s) + return lines + + +def write_func_call(name, arg_list, decl_map, indent=" "): + """write the C function call in Cython""" + # get argument list of the subroutine + in_args = [] + for arg in arg_list: + code, shape = decl_map.get(arg, ("", "")) + if 'dimension' in code.lower(): + in_args.append(f'{arg}_np.base') + else: + in_args.append(f'{arg}[0]') + + out_args = [] + for arg in arg_list: + code, _ = decl_map.get(arg, ("", "")) + match = re.search(r'intent\(out\)|intent\(inout\)', code, re.IGNORECASE) + if match: + s = f'{arg}_np' if 'dimension' in code.lower() else f'{arg}[0]' + out_args.append(s) + funcname = f' = ({name[3:].lower()})(' if len(out_args) > 0 else f'({name[3:].lower()})(' + prefix = indent + ','.join(out_args) + funcname + lines = wrap_comma_list(prefix=prefix, + items=in_args, + subsequent_indent=len(prefix)*' ') + + return lines + + +def write_assert(arg_list, decl_map, indent=" "): + def repl(m: re.Match) -> str: + ident, offset = m.groups() + return f'{ident}[0]{offset}' + + lines = [] + for arg in arg_list: + code, shape = decl_map.get(arg, ("", "")) + if 'dimension' not in code.lower(): + continue + + base_type = re.match(r'(integer|real|logical|character)', code).group(1).lower() + n_colons = len(shape.split(',')) + s_colons = ':,' * (n_colons - 1) + s_colons = "::1" if n_colons == 1 else \ + "::1," + s_colons[:-1] # remove last comma + s = f'cdef {TYPE_MAP[base_type]}[{s_colons}] {arg}_new' + lines.append(indent + s) + s_colons = '0,' * n_colons + s_colons = s_colons[:-1] # remove last comma + s = f'if {arg} != &{arg}_np[{s_colons}]:' + lines.append(indent + s) + colons = shape.split(',') + n_colons = len(colons) + s_colons = [] + for i in range(n_colons): + pat = re.compile(r'\b([A-Za-z_]\w*)'r'(\s*(?:[+-]\s*\d+)?)') + s_col = ':' + pat.sub(repl, colons[i].strip()) + s_col = s_col + ':1' if i == 0 else s_col + s_colons.append(s_col) + s_colons = ",".join(s_colons) # remove last comma + if 'dimension(:' in code.lower(): + s_colons = [f':{arg}_dim[{i}]' for i in range(1, n_colons)] + s_colons = f':{arg}_dim[0]:1,' if n_colons == 1 else \ + ",".join(s_colons) # remove last comma + s = f'{arg}_new = np.asarray(<{TYPE_MAP[base_type]}[{s_colons}]> {arg}, order="F")' + lines.append(2*indent + s) + s = f'{arg}_new[...] = {arg}_np' + lines.append(2*indent + s) + s = f'warnings.warn("The memory address of {arg} is changed in c__add_obs_err_pdaf."' + lines.append(2*indent + s) + s = '"The values are copied to the original Fortran array, and can slow-down the system.", RuntimeWarning)' + lines.append(3*indent + s) + + return lines + + +def generate_pyx(name, arg_list, decls, comments): + """ + name : original subroutine name (string) + arg_list : list of argument names in order, already lowercased + decls : list of (var, decl_code) from extract_declarations_by_args + comments : dict var->comment_str + """ + + lines = [] + # replace procedure argument names with their procedure type names + decl_map = { var: (code, shape) for var, code, shape in decls } + pyx_in_arg_list, pyx_out_arg_list = get_pyx_arg(arg_list, decl_map) + for arg in arg_list: + code, _ = decl_map.get(arg, ("", "")) + match = re.search(r'procedure\((.*?)\)', code) + if match: + proc_type = match.group(1).lower() + decl_map[proc_type] = decl_map.pop(arg) + comments[proc_type] = comments.pop(arg) + + # write the function signature + lines_sig = write_c_signature(name, arg_list, decl_map) + lines.extend(lines_sig) + + # write the function body + # memory views + lines_mv = write_memory_view(arg_list, decl_map) + lines.extend(lines_mv) + + lines.append("") + + lines_call = write_func_call(name, arg_list, decl_map) + lines.extend(lines_call) + + lines.append("") + + lines_assert = write_assert(pyx_out_arg_list, decl_map) + lines.extend(lines_assert) + + return "\n".join(lines) + + +def process_file(filepath, dst_dir): + lines = write_header() + + filename = filepath.stem + '.pyx' + output_path = Path(dst_dir) / filename + output_path.parent.mkdir(parents=True, exist_ok=True) + with open(output_path, 'a') as f: + f.write( "\n".join(lines)) + f.write( "\n\n") + + cb_interface = get_decls_cb.get_c_def(filepath.parent) + for name in cb_interface: + arg_list = cb_interface[name]['args'] + decls = cb_interface[name]['decls'] + comments = cb_interface[name]['comments'] + + extern_decls = generate_pyx(name, arg_list, decls, comments) + + with open(output_path, 'a') as f: + f.write(extern_decls + "\n\n\n") + + # except Exception as e: + # print(f"Skipping block in {filepath}: {e}") + + +def process_directory(src_dir, dst_dir): + for path in Path(src_dir).rglob("*"): + if path.suffix.lower() in (".f90"): + if path.stem == "pdaf_c_cb_interface": + process_file(path, dst_dir) + + +if __name__ == "__main__": + # process_directory('/home/users/ia923171/pyPDAF_dev/pyPDAF/src/fortran', '') + process_directory('/home/users/ia923171/pyPDAF_dev/pyPDAF/src/fortran', '/home/users/ia923171/pyPDAF_dev/pyPDAF/src/pyPDAF') diff --git a/pyPDAF/source/tool/write_pdaf_pxd.py b/pyPDAF/source/tool/write_pdaf_pxd.py new file mode 100644 index 0000000000000000000000000000000000000000..6b3ae385bbffe73a36e6bd6c32f5bdd93940f757 --- /dev/null +++ b/pyPDAF/source/tool/write_pdaf_pxd.py @@ -0,0 +1,139 @@ +import re +from pathlib import Path +import get_decls +import get_decls_cb + +WRAP_WIDTH = 80 + +TYPE_MAP = { + 'integer': 'int* ', + 'real': 'double* ', + 'logical': 'bint* ', + 'character': 'char* ' +} + + + +def wrap_comma_list(prefix, arg_list, decl_map, cb_interface, subsequent_indent=" ", suffix="", write_arg=True): + """ + Wrap a comma-separated list under WRAP_WIDTH, inserting '&' + at end of every line except the last, and appending `suffix` + (e.g. ' bind(c)') to that last line. + """ + lines = [] + current = prefix + for i, arg in enumerate(arg_list): + arg_str = arg if write_arg else '' + sep = ", " if i < len(arg_list) - 1 else ")" + suffix if suffix else ')' + code, _ = decl_map.get(arg, ("", "")) + # check user-supplied procedures + match = re.search(r'procedure\((.*?)\)', code) + if match: + if current != subsequent_indent: + lines.append(current) + current = subsequent_indent + addition = "" + + proc_type = match.group(1) + assert proc_type in cb_interface, f'{proc_type} is not in cb_interface' + # if this is a C binding, we need to use the C interface name + decl_map_cb = { var: (code, shape) for var, code, shape in cb_interface[proc_type]['decls'] } + cb_prefix = subsequent_indent + f'void (*{proc_type.lower()})(' + addition_list = wrap_comma_list( + prefix=cb_prefix, + arg_list=cb_interface[proc_type]['args'], + decl_map=decl_map_cb, + cb_interface=cb_interface, + subsequent_indent=" "*len(cb_prefix), + suffix=sep, + write_arg=False + ) + lines.extend(addition_list) + elif 'pointer' in code or 'dimension(:' in code.lower(): + addition = f'CFI_cdesc_t* ' + arg_str.lower() + sep + else: + base_type = re.match(r'(integer|real|logical|character)', code).group(1).lower() + c_type = TYPE_MAP[base_type] + addition = c_type + arg_str.lower() + sep + + # if adding this would exceed limit (allowing space for ' &' on wrapped lines) + if len(current) + len(addition) + (4 if sep==", " else len(suffix)) > WRAP_WIDTH: + lines.append(current) + current = subsequent_indent + addition + else: + current += addition + + # if items were empty, we might have just the prefix + if current == prefix: + current += ")" + suffix if suffix else ')' + + lines.append(current) + return lines + + +def generate_extern_pxd(name, arg_list, decls, cb_interface): + """ + name : original subroutine name (string) + arg_list : list of argument names in order, already lowercased + decls : list of (var, decl_code) from extract_declarations_by_args + comments : dict var->comment_str + """ + decl_map = { var: (code, shape) for var, code, shape in decls } + + lines = wrap_comma_list( + prefix=f"cdef extern void {name.lower()}(", + arg_list=arg_list, + decl_map=decl_map, + cb_interface=cb_interface, + suffix=" noexcept nogil;" + ) + lines.append("") + return "\n".join(lines) + +def process_file(filepath, dst_dir): + + cb_interface = get_decls_cb.get_c_def(filepath.parent) + + with open(filepath, 'r') as f: + lines = f.readlines() + + blocks = get_decls.extract_subroutine_blocks(lines) + + if not blocks: + print (f"No subroutines found in {filepath}") + return # No subroutines, skip + + filename = filepath.stem + '.pxd' + output_path = Path(dst_dir) / filename + output_path.parent.mkdir(parents=True, exist_ok=True) + with open(output_path, 'a') as f: + f.write("from .cfi_binding cimport CFI_cdesc_t\n") + + + for block in blocks: + name, arg_list, start_idx = get_decls.extract_multiline_signature(block) + decls, _ = get_decls.extract_declarations_by_args(block, start_idx, arg_list) + missing, extra = get_decls.compare_signature_and_declarations(arg_list, decls) + if missing: + print(f"!!! Missing declarations for: {missing} in {name} in {filepath}") + if extra: + print(f"!!! Declared but not in signature: {extra} in {name} in {filepath}") + + extern_decls = generate_extern_pxd(name, arg_list, decls, cb_interface) + + filename = filepath.stem + '.pxd' + output_path = Path(dst_dir) / filename + output_path.parent.mkdir(parents=True, exist_ok=True) + with open(output_path, 'a') as f: + f.write(extern_decls + "\n") + +def process_directory(src_dir, dst_dir): + for path in Path(src_dir).rglob("*"): + if path.suffix.lower() in (".f90"): + if path.stem == "pdaf_c_cb_interface": + continue + process_file(path, dst_dir) + +if __name__ == "__main__": + # process_directory('/home/users/ia923171/pyPDAF_dev/pyPDAF/src/fortran', '') + process_directory('/home/users/ia923171/pyPDAF_dev/pyPDAF/src/fortran', '/home/users/ia923171/pyPDAF_dev/pyPDAF/src/pyPDAF') diff --git a/pyPDAF/source/tool/write_pdaf_pyx.py b/pyPDAF/source/tool/write_pdaf_pyx.py new file mode 100644 index 0000000000000000000000000000000000000000..814bfcd23abc2898cfa25723ed62adc641a9e3a6 --- /dev/null +++ b/pyPDAF/source/tool/write_pdaf_pyx.py @@ -0,0 +1,523 @@ +import re +from pathlib import Path +import get_decls +import get_decls_cb +from docstring import docstrings + + +WRAP_WIDTH = 80 + +TYPE_MAP = { + 'integer': 'int ', + 'real': 'double ', + 'logical': 'bint ', + 'character': 'char ' +} + +TYPE_MAP_ARR = { + 'integer': 'np.intc', + 'real': 'np.float64', + 'logical': 'np.bool', + 'character': 'np.str_' +} + +TYPE_MAP_CNP = { + 'integer': 'cnp.int32_t', + 'real': 'cnp.float64_t', +} + + + +DUMMY_DOC = "Checking the corresponding PDAF documentation in https://pdaf.awi.de\n" \ + " For internal subroutines checking corresponding PDAF comments." + + +def write_header(): + lines = [] + lines.append("import sys") + lines.append("import numpy as np") + lines.append("cimport numpy as cnp") + lines.append("from . cimport pdaf_c_cb_interface as pdaf_cb") + lines.append("from .cfi_binding cimport CFI_cdesc_t, CFI_address, CFI_index_t, CFI_establish") + lines.append("from .cfi_binding cimport CFI_attribute_other, CFI_type_double, CFI_type_int") + lines.append("from .cfi_binding cimport CFI_cdesc_rank1, CFI_cdesc_rank2, CFI_cdesc_rank3") + lines.append("") + lines.append("try:") + lines.append(" import mpi4py") + lines.append(" mpi4py.rc.initialize = False") + lines.append("except ImportError:") + lines.append(" pass") + lines.append("") + lines.append("# Global error handler") + lines.append("def global_except_hook(exctype, value, traceback):") + lines.append(" from traceback import print_exception") + lines.append(" try:") + lines.append(" import mpi4py.MPI") + lines.append("") + lines.append(" if mpi4py.MPI.Is_initialized():") + lines.append(" try:") + lines.append(" sys.stderr.write('Uncaught exception was '" + "'detected on rank {}.\\n'.format(") + lines.append(" mpi4py.MPI.COMM_WORLD.Get_rank()))") + + lines.append(" print_exception(exctype, value, traceback)") + lines.append(" sys.stderr.write(\"\\n\")") + lines.append(" sys.stderr.flush()") + lines.append(" finally:") + lines.append(" try:") + lines.append(" mpi4py.MPI.COMM_WORLD.Abort(1)") + lines.append(" except Exception as e:") + lines.append(" sys.stderr.write('MPI Abort failed, this process will hang.\\n')") + lines.append(" sys.stderr.flush()") + lines.append(" raise e") + lines.append(" else:") + lines.append(" sys.__excepthook__(exctype, value, traceback)") + lines.append(" except ImportError:") + lines.append(" sys.__excepthook__(exctype, value, traceback)") + lines.append("") + lines.append("sys.excepthook = global_except_hook") + + return lines + + +def get_pyx_arg(arg_list, decl_map): + pyx_in_arg_list = [] + pyx_out_arg_list = [] + for arg in arg_list: + code, _ = decl_map.get(arg, ("", "")) + match = re.search(r'procedure\((.*?)\)', code) + if match: + proc_type = match.group(1).lower() + pyx_in_arg_list.append(proc_type.replace("c__", "py__")) + else: + match = re.search(r'intent\(in\)|intent\(inout\)', code, re.IGNORECASE) + if match: + # currently only pdafomi_diag has intent(inout) pointers + # we do not take input pointers + if 'pointer' not in code.lower(): + pyx_in_arg_list.append(arg) + match = re.search(r'intent\(out\)', code, re.IGNORECASE) + if match and 'dimension(:' in code.lower() and 'pointer' not in code.lower(): + # if it's an assumed shape output array, we need to handle it differently + # it will need an input array to establish a CFI + pyx_in_arg_list.append(arg) + match = re.search(r'intent\(out\)|intent\(inout\)', code, re.IGNORECASE) + if match: + pyx_out_arg_list.append(arg) + return pyx_in_arg_list, pyx_out_arg_list + + +def wrap_comma_list(prefix, items, subsequent_indent=" ", suffix=""): + """ + Wrap a comma-separated list under WRAP_WIDTH, inserting '&' + at end of every line except the last, and appending `suffix` + (e.g. ' bind(c)') to that last line. + """ + lines = [] + current = prefix + for i, item in enumerate(items): + sep = ", " if i < len(items) - 1 else ")" + addition = item + sep + # if adding this would exceed limit (allowing space for ' &' on wrapped lines) + if len(current) + len(addition) + (4 if sep==", " else len(suffix)) > WRAP_WIDTH: + lines.append(current) + current = subsequent_indent + item + sep + else: + current += addition + # if items were empty, we might have just the prefix + if current == prefix: + current += ")" + + # append suffix to the final line + if suffix: + current = current + suffix + lines.append(current) + return lines + + +def write_pyx_signature(pyx_name, arg_list, decl_map): + pyx_def_arg_list = [] + for arg in arg_list: + code, shape = decl_map.get(arg, ("", "")) + if 'dimension' in code.lower(): + n_colons = len(shape.split(',')) - 1 + s_colons_t = ':,' * n_colons + s_colons = "::1" if n_colons == 0 else \ + "::1," + s_colons_t[:-1] # remove last comma + base_type = re.match(r'(integer|real|logical|character)', code).group(1).lower() + pyx_def_arg_list.append(f'{TYPE_MAP[base_type]}[{s_colons}] {arg}') + elif 'procedure' in code.lower(): + pyx_def_arg_list.append(arg) + else: + base_type = re.match(r'(integer|real|logical|character)', code).group(1).lower() + pyx_def_arg_list.append(f'{TYPE_MAP[base_type]} {arg}') + + return wrap_comma_list( + prefix=f"def {pyx_name}(", + items=pyx_def_arg_list, + suffix=":" + ) + + +def get_docstring_type(code, shape): + if 'procedure' in code.lower(): + return 'Callable' + elif 'dimension' in code.lower(): + base_type = re.match(r'(integer|real|logical|character)', code).group(1).lower() + return f'ndarray[{TYPE_MAP_ARR[base_type]}, ndim={len(shape.split(","))}]' + else: + base_type = re.match(r'(integer|real|logical|character)', code).group(1).lower() + return TYPE_MAP[base_type] + + +def write_docstring_args(arg_in_list, arg_out_list, cb_interface, decl_map, comments, + callback="", indent=" "): + lines = [] + if len(arg_in_list) > 0: + lines.append('') + header = f'{callback} Parameters'.strip() + lines.append(indent + header) + lines.append(indent+'-'*len(header)) + for arg in arg_in_list: + code, shape = decl_map.get(arg, ("", "")) + arg_type = get_docstring_type(code, shape) + lines.append(indent + f'{arg} : {arg_type}') + lines.append(2*indent + f'\n{2*indent}'.join(comments[arg])) + if 'dimension' in code.lower(): + lines.append(2*indent + f'Array shape: ({shape})') + if arg_type == 'Callable': + decl_cb_map = {arg_cb: (code, shape) + for arg_cb, code, shape in cb_interface[arg]['decls']} + com_lines = write_docstring_args(cb_interface[arg]['pyx_in_args'], + cb_interface[arg]['pyx_out_args'], + cb_interface, + decl_cb_map, + cb_interface[arg]['comments'], + indent=2*indent, + callback="Callback") + lines.extend(com_lines) + lines.append('') + + if len(arg_in_list) > 0: + lines.append('') + header = f'{callback} Returns'.strip() + lines.append(indent + header) + lines.append(indent+'-'*len(header)) + for arg in arg_out_list: + code, shape = decl_map.get(arg, ("", "")) + arg_type = get_docstring_type(code, shape) + lines.append(indent + f'{arg} : {arg_type}') + lines.append(2*indent + f'\n{2*indent}'.join(comments[arg])) + if 'dimension' in code.lower(): + lines.append(2*indent + f'Array shape: ({shape})') + + return lines + + +def write_memory_view(arg_list, decl_map, indent=" "): + """Convert 2D arrays to fortran contiguous arrays + """ + # convert np arrays to memoryview + lines = [] + for arg in arg_list: + code, shape = decl_map.get(arg, ("", "")) + if 'dimension' not in code.lower(): + # not a Fortran array, skip + continue + + if 'dimension(:' in code.lower(): + n_dim = len(shape.split(',')) + s = f'cdef CFI_cdesc_rank{n_dim} {arg}_cfi' + lines.append(indent + s) + s = f'cdef CFI_cdesc_t *{arg}_ptr = &{arg}_cfi' + lines.append(indent + s) + if 'pointer' in code.lower(): + continue + + s = f'cdef size_t {arg}_nbytes = {arg}.nbytes' + lines.append(indent + s) + s = f'cdef CFI_index_t {arg}_extent[{n_dim}]' + lines.append(indent + s) + for i in range(n_dim): + s = f'{arg}_extent[{i}] = {arg}.shape[{i}]' + lines.append(indent + s) + + n_colons = len(shape.split(',')) - 1 + s_colons_t = ':,' * n_colons + s_colons = "::1" if n_colons == 0 else \ + "::1," + s_colons_t[:-1] # remove last comma + base_type = re.match(r'(integer|real|logical|character)', code).group(1).lower() + s = f'cdef cnp.ndarray[{TYPE_MAP_CNP[base_type]}, ndim={n_colons+1}, mode="fortran", negative_indices=False, cast=False] ' + if 'intent(out)' in code.lower() and 'dimension(:' not in code.lower(): + s += f'{arg}_np = np.zeros(({shape}), dtype={TYPE_MAP_ARR[base_type]}, order="F")' + lines.append(indent + s) + s = f'cdef {TYPE_MAP[base_type]}[{s_colons}] {arg} = {arg}_np' + lines.append(indent + s) + else: + s += f'{arg}_np = np.asarray({arg}, dtype={TYPE_MAP_ARR[base_type]}, order="F")' + lines.append(indent + s) + return lines + + +def write_input_cfi(arg_list, decl_map, indent=" "): + """Convert 2D arrays to fortran contiguous arrays + """ + # convert np arrays to memoryview + lines = [] + for arg in arg_list: + code, shape = decl_map.get(arg, ("", "")) + if 'dimension' not in code.lower(): + # not a Fortran array, skip + continue + + if 'intent(inout)' in code.lower(): + continue + if 'intent(out)' in code.lower(): + continue + + if 'dimension(:' in code.lower(): + n_dim = len(shape.split(',')) + s = f'cdef CFI_cdesc_rank{n_dim} {arg}_cfi' + lines.append(indent + s) + s = f'cdef CFI_cdesc_t *{arg}_ptr = &{arg}_cfi' + lines.append(indent + s) + if 'pointer' in code.lower(): + continue + s = f'cdef size_t {arg}_nbytes = {arg}.nbytes' + lines.append(indent + s) + s = f'cdef CFI_index_t {arg}_extent[{n_dim}]' + lines.append(indent + s) + for i in range(n_dim): + s = f'{arg}_extent[{i}] = {arg}.shape[{i}]' + lines.append(indent + s) + + return lines + + +def write_user_cython(arg_list, decl_map, indent=' '): + """convert python function to Cython function""" + lines = [] + for arg in arg_list: + code, _ = decl_map.get(arg, ("", "")) + if 'procedure' in code.lower(): + lines.append(indent+ f'pdaf_cb.{arg.replace("py__", "")} = {arg}') + return lines + + +def write_return_def(arg_list, decl_map, indent=' '): + lines = [] + for arg in arg_list: + code, _ = decl_map.get(arg, ("", "")) + if 'intent(inout)' in code.lower(): + # only define pure return arguments + continue + if 'dimension' in code.lower(): + # array and pointers are defined in memory view + continue + base_type = re.match(r'(integer|real|logical|character)', code).group(1).lower() + s = f'cdef {TYPE_MAP[base_type]} {arg}' + lines.append(indent + s) + return lines + + +def write_func_call(name, arg_list, decl_map, indent=" "): + """write the C function call in Cython""" + # special treatment for init subroutine + lines = [indent + 'with nogil:'] + # establish CFI for assumed shape arrays + for arg in arg_list: + code, shape = decl_map.get(arg, ("", "")) + if 'dimension' not in code.lower(): + # not a Fortran array, skip + continue + if 'pointer' in code.lower(): + # pointer arrays do not need CFI_establish with CFI + continue + + if 'dimension(:' in code.lower(): + n_dim = len(shape.split(',')) + s_zeros = '0,' * n_dim + s_zeros = s_zeros[:-1] + base_type = re.match(r'(integer|real|logical|character)', code).group(1).lower() + s = f'CFI_establish({arg}_ptr, &{arg}[{s_zeros}], CFI_attribute_other,' + lines.append(2*indent + s) + s = f'CFI_type_{TYPE_MAP[base_type]}, {arg}_nbytes, {n_dim}, {arg}_extent)' + lines.append(2*indent + len('CFI_establish(')*' ' + s) + lines.append("") + + # get argument list of the subroutine + c_args = [] + for arg in arg_list: + code, shape = decl_map.get(arg, ("", "")) + if 'dimension(:' in code.lower(): + c_args.append(f'{arg}_ptr') + elif 'dimension' in code.lower(): + n_zeros = len(shape.split(',')) + s_zeros = '0,' * n_zeros + s_zeros = s_zeros[:-1] + c_args.append(f'&{arg}[{s_zeros}]') + elif 'procedure' in code.lower(): + proc_type = re.search(r'procedure\((.*?)\)', code).group(1).lower() + c_args.append(f'pdaf_cb.{proc_type.replace("py__", "c__")}') + else: + c_args.append(f'&{arg}') + prefix = 2*indent + f'{name.lower()}(' + lines_call = wrap_comma_list(prefix=prefix, + items=c_args, + subsequent_indent=len(prefix)*' ') + + lines.extend(lines_call) + lines.append("") + + return lines + + +def write_return(arg_list, decl_map, indent=" "): + if len(arg_list) == 0: + return [] + lines = [] + + for arg in arg_list: + code, shape = decl_map.get(arg, ("", "")) + if 'pointer' in code.lower(): + n_dim = len(shape.split(',')) + s = f'cdef CFI_index_t {arg}_subscripts[{n_dim}]' + lines.append(indent + s) + for i in range(n_dim): + s = f'{arg}_subscripts[{i}] = 0' + lines.append(indent + s) + base_type = re.match(r'(integer|real|logical|character)', code).group(1).lower() + s = f'cdef {TYPE_MAP[base_type]}* {arg}_ptr_np' + lines.append(indent + s) + s = f'{arg}_ptr_np = <{TYPE_MAP[base_type]}*>CFI_address({arg}_ptr, {arg}_subscripts)' + lines.append(indent + s) + s = f'cdef cnp.ndarray[{TYPE_MAP_CNP[base_type]}, ndim={n_dim}, mode="fortran", negative_indices=False, cast=False] ' + s_colons = f':{arg}_ptr.dim[0].extent:1' + s_colons += ',' if n_dim > 1 else '' + s_colons += ','.join([f':{arg}_ptr.dim[{i}].extent' for i in range(1, n_dim)]) + s += f'{arg}_np = np.asarray(<{TYPE_MAP[base_type]}[{s_colons}]> {arg}_ptr_np, order="F")' + lines.append(indent + s) + + s = 'return ' + for arg in arg_list: + code, shape = decl_map.get(arg, ("", "")) + s += f'{arg}_np, ' if 'dimension' in code.lower() else f'{arg}, ' + + lines.append(indent + s[:-2]) + return lines + + +def generate_pyx(name, arg_list, decls, comments, cb_interface, is_internal): + """ + name : original subroutine name (string) + arg_list : list of argument names in order, already lowercased + decls : list of (var, decl_code) from extract_declarations_by_args + comments : dict var->comment_str + """ + + lines = [] + # replace procedure argument names with their procedure type names + decl_map = { var: (code, shape) for var, code, shape in decls } + pyx_in_arg_list, pyx_out_arg_list = get_pyx_arg(arg_list, decl_map) + c_arg_list = [] + for arg in arg_list: + code, _ = decl_map.get(arg, ("", "")) + match = re.search(r'procedure\((.*?)\)', code) + if match: + proc_type = match.group(1).lower() + decl_map[proc_type.replace("c__", "py__")] = decl_map.pop(arg) + comments[proc_type.replace("c__", "py__")] = comments.pop(arg) + cb_interface[proc_type.replace("c__", "py__")] = cb_interface.pop(proc_type) + c_arg_list.append(proc_type.replace('c__','py__')) + else: + c_arg_list.append(arg) + + # write the function signature + pyx_name = re.sub(r'c__pdaf_', '_' if is_internal else '', name.lower()) + pyx_name = re.sub(r'c__pdafomi_', '_' if is_internal else '', pyx_name.lower()) + pyx_name = re.sub(r'c__pdaflocal_', '_' if is_internal else '', pyx_name.lower()) + pyx_name = re.sub(r'c__pdaflocalomi_', '_' if is_internal else '', pyx_name.lower()) + pyx_name = re.sub(r'c__pdaf3_', '_' if is_internal else '', pyx_name.lower()) + pyx_name = re.sub(r'c__pdaf', '_' if is_internal else '', pyx_name.lower()) + lines_sig = write_pyx_signature(pyx_name, pyx_in_arg_list, decl_map) + lines.extend(lines_sig) + + # write the docstrings + lines.append(' """' + docstrings.docstrings.get(pyx_name, DUMMY_DOC)) + lines_args = write_docstring_args(pyx_in_arg_list, pyx_out_arg_list, + cb_interface, decl_map, comments) + lines.extend(lines_args) + lines.append(' """') + + # write the function body + # memory views + lines_mv = write_memory_view(pyx_out_arg_list, decl_map) + lines.extend(lines_mv) + + lines_cfi = write_input_cfi(pyx_in_arg_list, decl_map) + lines.extend(lines_cfi) + + lines_cb = write_user_cython(pyx_in_arg_list, decl_map) + lines.extend(lines_cb) + + lines_return_def = write_return_def(pyx_out_arg_list, decl_map) + lines.extend(lines_return_def) + + lines_call = write_func_call(name, c_arg_list, decl_map) + lines.extend(lines_call) + + lines_return = write_return(pyx_out_arg_list, decl_map) + lines.extend(lines_return) + + return "\n".join(lines) + + +def process_file(filepath, dst_dir): + + with open(filepath, 'r') as f: + lines = f.readlines() + + blocks = get_decls.extract_subroutine_blocks(lines) + + if not blocks: + print (f"No subroutines found in {filepath}") + return # No subroutines, skip + lines = write_header() + + filename = filepath.stem + '.pyx' + output_path = Path(dst_dir) / filename + output_path.parent.mkdir(parents=True, exist_ok=True) + with open(output_path, 'a') as f: + f.write( "\n".join(lines)) + f.write( "\n\n") + + for block in blocks: + # try: + cb_interface = get_decls_cb.get_pyx_def(filepath.parent) + name, arg_list, start_idx = get_decls.extract_multiline_signature(block) + decls, comments = get_decls.extract_declarations_by_args(block, start_idx, arg_list) + missing, extra = get_decls.compare_signature_and_declarations(arg_list, decls) + if missing: + print(f"!!! Missing declarations for: {missing} in {name} in {filepath}") + if extra: + print(f"!!! Declared but not in signature: {extra} in {name} in {filepath}") + + extern_decls = generate_pyx(name, arg_list, decls, comments, cb_interface, is_internal='internal' in filepath.stem) + + with open(output_path, 'a') as f: + f.write(extern_decls + "\n\n\n") + + # except Exception as e: + # print(f"Skipping block in {filepath}: {e}") + + +def process_directory(src_dir, dst_dir): + for path in Path(src_dir).rglob("*"): + if path.suffix.lower() in (".f90"): + if path.stem == "pdaf_c_cb_interface": + continue + process_file(path, dst_dir) + +if __name__ == "__main__": + # process_directory('/home/users/ia923171/pyPDAF_dev/pyPDAF/src/fortran', '') + process_directory('/home/users/ia923171/pyPDAF_dev/pyPDAF/src/fortran', '/home/users/ia923171/pyPDAF_dev/pyPDAF/src/pyPDAF') diff --git a/pyPDAF/source/tutorials/tutorial1_serial.ipynb b/pyPDAF/source/tutorials/tutorial1_serial.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..dd1b7130e71c412939fe2c33dd61720f483bd0a1 --- /dev/null +++ b/pyPDAF/source/tutorials/tutorial1_serial.ipynb @@ -0,0 +1,1154 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "PACl2a3eN4Sy" + }, + "source": [ + "# Building an Assimilation System with pyPDAF without parallelisation\n", + "\n", + "---\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eBE84vfB5OY6" + }, + "source": [ + "pyPDAF is a Python interface to PDAF (Parallel Data Assimilation Framework). The framework is mainly designed for ensemble data assimilation systems with high-dimensional complex weather and climae models. It has applications to both research and operational purposes. The Python interface allows for the use of PDAF in Python, a flexible and rich environment.\n", + "\n", + "As per its name, the framework is designed with the aim to implement efficient parallelised data assimilation system. In this practical, we provide a step-by-step tutorial on constructing a DA system with pyPDAF without using parallelisation. This tutorial is a simplification of the code used in `example/online` directory." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-maLnxQirCAv" + }, + "source": [ + "## Install pyPDAF\n", + "---\n", + "Before discussing the DA system construction, let us install pyPDAF first. If you are familiar with Python, you might have the package manager `conda` installed. This can be obtained using `anaconda` or `miniconda`." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "p6Es_i7wGBNI" + }, + "source": [ + "### On local computer:\n", + "\n", + "In your terminal or anaconda prompt, run `conda create -n pypdaf -c conda-forge yumengch::pypdaf conda-forge::jupyter`.\n", + "\n", + "You can then open this notebook using the command `jupyter notebook`\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lSsjNPl-F1On" + }, + "source": [ + "### On Google Colab (skip this section when you're not using Google Colab):" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vpxjlTuLSZ8H" + }, + "source": [ + "The following step will install `conda` on the Google Colab. Here, as the conda installation on Google Colab is a bit awkward. We build pyPDAF from source code." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "VcRt2oa8N3fo" + }, + "outputs": [], + "source": [ + "!git clone --recurse-submodules https://github.com/yumengch/pyPDAF.git # get source code\n", + "# change to pyPDAF directory\n", + "%cd pyPDAF\n", + "# build pyPDAF. This could take a few minutes\n", + "!CC=mpicc FC=mpifort python -m pip install . --config-settings=setup-args=\"-Dblas_lib=['openblas',]\"\n", + "# return original directory\n", + "%cd .." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "pNy2ubUw7Bl3" + }, + "source": [ + "To provide a better view of PDAF output, we have to use wurlitzer" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rg78gjS36VOi" + }, + "source": [ + "## Model and Observations\n", + "\n", + "In a typical data assimilation application, one usually has a model that can simulate the system of interest. For example, in the numerical weather prediction, an atmosphere model is available. The same applies to ocean, sea ice, biogeochemistry and land surface models. These models usually provide a priori estimate (forecast) of the state of the system in sequential data assimilation schemes, or an initial guess/background state in variational methods. The motivation of data assimilation system is to obtain a good estimate of the state of the system with observations, which makes up another important component of data assimilation.\n", + "\n", + "When constructing a data assimilation system in pyPDAF, providing the model state and observation as well as their connection and uncertainty information is the key task. Before we get into pyPDAF, let's look at the example model and observations in this tutorial." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9cGn7y1usALz" + }, + "source": [ + "### Model" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "aHTqZ_SkHyYL" + }, + "source": [ + "In this tutorial, a 2D model that propagates a sine wave along in a rectangular domain is used for demonstration purpose. The model integration can be represented by a `step` function:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "ygfYHHWf_UgI" + }, + "outputs": [], + "source": [ + "\"\"\"define the model integration step\"\"\"\n", + "import numpy as np\n", + "\n", + "def step(field: np.ndarray) -> np.ndarray:\n", + " \"\"\"Roll array elements of i-th time step along a the first axis.\"\"\"\n", + " return np.roll(field, shift=1, axis=-2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "y64udCFg6VOk" + }, + "source": [ + "In the tutorial, the model has\n", + "- Spatial Domain: Two dimensional domain grid domain with $(nx \\times ny) = (36 \\times 18)$ grid points\n", + "- Total steps: we will run this model by `nsteps = 18` time steps" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "pHBcpFqo4d-i" + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "# define the array for model field\n", + "nsteps = 18 # total time steps\n", + "nx = 36 # 36 columns\n", + "ny = 18 # 18 rows\n", + "# initial condition + 18 time steps, 18 rows and 36 columns\n", + "field = np.zeros((nsteps + 1, ny, nx))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vD5fxabx6VOk" + }, + "source": [ + "For the sake of simplicity, a true initial condition is provided:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "0_TOr4rAIAsp" + }, + "outputs": [], + "source": [ + "\"\"\" this is a way to get all required data without using git and introducing additional libraries\"\"\"\n", + "import os\n", + "import urllib.request\n", + "# create input data directory\n", + "os.makedirs('inputs_online', exist_ok=True)\n", + "link_to_files = 'https://raw.githubusercontent.com/yumengch/pyPDAF/refs/heads/main/example/inputs_online/'\n", + "# get the initial truth\n", + "urllib.request.urlretrieve(f'{link_to_files}/true_initial.txt', os.path.join('inputs_online','true_initial.txt'))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7KCHJ4YD-mEC" + }, + "source": [ + "We can read the initial condition to model field array:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "XCiMLV48_U3o" + }, + "outputs": [], + "source": [ + "\"\"\"read the initial condition of the model field\"\"\"\n", + "field[0] = np.loadtxt(os.path.join('inputs_online','true_initial.txt'))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5OhqIzCSwNij" + }, + "source": [ + "Now, we can visualise the model evolution:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "cz44hSkm19hg" + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "from matplotlib import animation\n", + "from IPython.display import HTML\n", + "fig = plt.figure('animation')\n", + "ax = fig.add_subplot(111)\n", + "pc = ax.pcolormesh(field[0], cmap='coolwarm', vmin=-1, vmax=1)\n", + "fig.colorbar(pc, ax=ax)\n", + "\n", + "def draw_model(i):\n", + " \"\"\"Draw each model step\n", + " \"\"\"\n", + " # run the model\n", + " field[i+1] = step(field[i])\n", + " pc.set_array(field[i+1])\n", + " ax.set_title(f'Model step {i+1}')\n", + " return pc,\n", + "\n", + "# make an animation\n", + "anim = animation.FuncAnimation(fig, draw_model, frames=nsteps, interval=1000, blit=True)\n", + "plt.close(fig)\n", + "HTML(anim.to_html5_video())" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "b-mYku6H84ud" + }, + "source": [ + "### Observations" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ax0O8IZM6VOm" + }, + "source": [ + "Observations are given for each time steps stored in 'obs_step*.txt'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "-qaOiytg6VOm" + }, + "outputs": [], + "source": [ + "\"\"\"retrieve observations\"\"\"\n", + "for i in range(nsteps):\n", + " urllib.request.urlretrieve(f'{link_to_files}/obs_step{i+1}.txt', os.path.join('inputs_online',f'obs_step{i+1}.txt'))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cggXCDYK6VOm" + }, + "source": [ + "- Among 648 grid points only 28 grid points have observations. This is because most DA methods can estimate grid points without observations by assuming each grid points form a multi-variate Gaussian distribution.\n", + "- Compared to the truth, these observations have an error of 0.5\n", + "- The retrieved data use `-999` as missing values" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "bg1G9Jxo9KpD" + }, + "outputs": [], + "source": [ + "# define observation array\n", + "obs = np.ma.zeros((nsteps, ny, nx))\n", + "fig = plt.figure('animationObs')\n", + "ax = fig.add_subplot(111)\n", + "pc = ax.pcolormesh(obs[0], cmap='coolwarm', vmin=-1, vmax=1)\n", + "fig.colorbar(pc, ax=ax)\n", + "def draw_model(i):\n", + " \"\"\"Draw obs. at each model step\n", + " \"\"\"\n", + " obs[i] = np.loadtxt(os.path.join('inputs_online', f'obs_step{i+1}.txt'))\n", + " obs[i] = np.ma.masked_where(np.isclose(obs[i], -999.), obs[i])\n", + " pc.set_array(obs[i])\n", + " ax.set_title(f'Observation at step {i+1}')\n", + " return pc,\n", + "\n", + "# make an animation\n", + "anim = animation.FuncAnimation(fig, draw_model, frames=18, interval=1000, blit=True)\n", + "plt.close(fig)\n", + "HTML(anim.to_html5_video())" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "c8yt_y_LNnVt" + }, + "source": [ + "In this tutorial, we can actually obtain the truth, " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "3B61rFyj6VOn" + }, + "outputs": [], + "source": [ + "for i in range(18):\n", + " # get all truth\n", + " urllib.request.urlretrieve(f'{link_to_files}/true_step{i+1}.txt', os.path.join('inputs_online', f'true_step{i+1}.txt'))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2zVEM0tX6VOn" + }, + "source": [ + "In comparison to the truth, we can check the observation error and calculate it as a sanity check." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "5U5Go0lKMRbH" + }, + "outputs": [], + "source": [ + "# calculate the root mean squared obs. err in time\n", + "err = np.sqrt(np.sum((field[1:] - obs)**2, axis=0)/nsteps)\n", + "# plot the observation error\n", + "fig = plt.figure('R')\n", + "ax = fig.add_subplot(111)\n", + "pc = ax.pcolormesh(err, cmap='Blues', vmin=0., vmax=1.)\n", + "ax.set_title(f'Spatial averaged obs. err is {np.round(np.mean(err), 3)}')\n", + "fig.colorbar(pc, ax=ax)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "SfRF0cTmPWI4" + }, + "source": [ + "## Set up a data assimilation system using pyPDAF" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "02QwMpZk6VOo" + }, + "source": [ + "Now, we can construct our data assimilation systems. As in many other Python programs, we use third-party packages for the system. This is one of the benefits of a Python system as many functionalities are available. In this tutorial, `pyPDAF`, `numpy` is used. As we do not utilise the parallel features of pyPDAF, `mpi4py` is not required." + ] + }, + { + "cell_type": "markdown", + "source": [], + "metadata": { + "id": "NNp4yViR7xZO" + } + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "c6uXE1iZ6VOo" + }, + "outputs": [], + "source": [ + "%%capture\n", + "\"\"\"For the sake of compatibility of running it in Google Colab, we install wurlitzer here.\n", + " This is not essential if you run it on your local computer, but you will need to remove\n", + " all code related to wurlitzer in this notebook.\"\"\"\n", + "# wurlitzer is a package that allows us to see PDAF output\n", + "!pip install wurlitzer" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "pzlLMXevPF8I" + }, + "outputs": [], + "source": [ + "import pyPDAF\n", + "import numpy as np\n", + "from wurlitzer import pipes" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Gwe4J1xVfGTK" + }, + "source": [ + "### Initialise PDAF\n", + "\n", + "The initialisation of PDAF tells PDAF the our choice of data assimilation algorithms, ensemble size, inflation factor, and the dimension of the state vector. Currently (up to PDAF V2.3.1), any DA methods in PDAF require these options. However, some methods can only be executed with additional parameters. This is done by [`PDAF.init`](https://yumengch.github.io/pyPDAF/PDAF.html#pyPDAF.PDAF.init).\n", + "\n", + "In this tutorial, the **error space transform Kalman filter (ESTKF)** is used with **9** ensemble members. We will estimate the state of every model grid point, which gives us a state vector with the size of nx × ny = 36 × 18 = 648. The `filtertype` and `subtype` here specifies the DA method and will be given as an argument in `pyPDAF.PDAF.init` function. A full list of supported methods can be found in [PDAF wiki](https://pdaf.awi.de/trac/wiki/AvailableOptionsforInitPDAF). We first put these information into Python variables." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "g4wDabInPY7O" + }, + "outputs": [], + "source": [ + "# using error space transform Kalman filter (ESTKF)\n", + "filtertype = 6\n", + "# standard form\n", + "subtype = 0\n", + "# dimension of the state vector\n", + "# if model is parallelised, this is the dimension of state vector on each process\n", + "dim_state_p = nx*ny\n", + "# number of ensemble members\n", + "dim_ens = 9\n", + "# forget factor\n", + "forget_factor = 1.0" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yrIrGKSvWrcu" + }, + "source": [ + "In addition to the above information, [`pyPDAF.init`](https://yumengch.github.io/pyPDAF/_autosummary/pyPDAF.init.html#pyPDAF.init) also asks for an **initial ensemble** for PDAF. This information is given by the user-supplied function [py__init_ens_pdaf](https://yumengch.github.io/pyPDAF/user_desc/py__init_ens_pdaf.html). These functions have fixed interface. Therefore\n", + "- the input arguments and return variables should not be changed.\n", + "- only the value of returned variables should be changed\n", + "\n", + "Documentation of the input arguments and return variable of this function can be found in [pyPDAF documentation](https://yumengch.github.io/pyPDAF/_autosummary/pyPDAF.init.html#pyPDAF.init). In this user-supplied function, the primary purpose is to fill the `ens_p` array. The `ens_p` is an array allocated by PDAF to perform data assimilation. Pure input arguments such as `filtertype`, `dim_p`, and `dim_ens` are given by PDAF. These information is given to PDAF when we call `pyPDAF.init`. When we implement the user-supplied function, they can be difficult to access. Therefore, PDAF provide these variables as input argument in the user-supplied function. For example, in this tutorial, the initial ensemble is read from text files. The `dim_ens` argument helps us the set up a loop to read these text files.\n", + "\n", + "In real applications, we may encouter different scenarios. For example, one may need to use algorithms to generate perturbations to create an initial ensemble from a model trajectory, see [PDAF functionality](https://pdaf.awi.de/trac/wiki/EnsembleGeneration). If one have an ensemble of model restart file, we can also simply return the variables in this user-supplied function." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "LIksYDywTetx" + }, + "outputs": [], + "source": [ + "def init_ens_pdaf(filtertype, dim_p, dim_ens, state_p, uinv, ens_p, status_pdaf):\n", + " \"\"\"Here, only ens_p variable matters while dim_p and dim_ens defines the\n", + " size of the variables. uinv, state_p are not used in this example.\n", + "\n", + " status_pdaf is used to handle errors which we will not do it in this example.\n", + " \"\"\"\n", + " # get initial ensemble\n", + " for i in range(dim_ens):\n", + " urllib.request.urlretrieve(f'{link_to_files}/ens_{i+1}.txt',\n", + " os.path.join('inputs_online', f'ens_{i+1}.txt'))\n", + " ens_p[:, i] = np.loadtxt(os.path.join('inputs_online', f'ens_{i+1}.txt')).ravel()\n", + " return state_p, uinv, ens_p, status_pdaf" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "tf8x0NGAfEz2" + }, + "source": [ + "With these information, we can call PDAF function `pyPDAF.init` to initialise the DA system." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "tb76E2-OPOPU" + }, + "outputs": [], + "source": [ + "# this gives the verbose level of the PDAF, here we use 3 which is very verbose\n", + "screen = 3\n", + "# current step of the model which is 0\n", + "current_step = 0\n", + "\n", + "with pipes() as (out, err):\n", + " _, _, status = pyPDAF.init(filtertype, subtype, current_step,\n", + " np.array([dim_state_p, dim_ens], dtype=np.intc), 2,\n", + " np.array([forget_factor, ]), 1,\n", + " py__init_ens_pdaf=init_ens_pdaf,\n", + " in_screen=screen)\n", + "# print PDAF screen output\n", + "print (out.read())" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HXpuKapDbnZN" + }, + "source": [ + "### Distribution of the ensemble from PDAF\n", + "After PDAF initialisation, PDAF should distribute the ensemble initialised in `init_ens_pdaf` to the model to initialise the following forecast. This is accomplished by [`pyPDAF.init_forecast`](https://yumengch.github.io/pyPDAF/_autosummary/pyPDAF.init_forecast.html#pyPDAF.init_forecast) function.\n", + "\n", + "This function depends on three user-supplied functions that are executed in the following sequence:\n", + "1. Processing the initial PDAF ensemble by user-supplied function [`py__prepoststep_state_pdaf`](https://yumengch.github.io/pyPDAF/user_desc/py__prepoststep_pdaf.html). This is because the ensemble stored in PDAF may not satisify some physical constraints such as balance conditions (hydrostatic balance/constitutive relations) or boundness (percentage values/chemical concentrations).\n", + "2. PDAF should distribute the initial ensemble to the model for following model forecasts in [`py__distribute_state_pdaf`](https://yumengch.github.io/pyPDAF/user_desc/py__distribute_state_pdaf.html). This function relates the model field to the state vector used by PDAF.\n", + "3. PDAF perform actual data assimilation based on its internal counter for the time steps. In `pyPDAF.init` function, we specify the initial time step. Now, a user-supplied function informs PDAF the data assimilation is performed after `nsteps` of forecast in [`py__next_observation_pdaf`](https://yumengch.github.io/pyPDAF/user_desc/py__next_observation_pdaf.html). The internal time step counter is incremented by one whenever one calls the assimilation functions.\n", + "\n", + "To implement these user-supplied functions, we define a `PdafDistributor` class." + ] + }, + { + "cell_type": "code", + "source": [ + "class PdafDistributor:\n", + " \"\"\"Distribute the ensemble members to the model tasks\n", + " \"\"\"\n", + " def __init__(self, nx, ny):\n", + " # define the model field based on the ensemble\n", + " self.nx, self.ny = nx, ny\n", + " self.field = np.zeros((ny, nx))" + ], + "metadata": { + "id": "fYtnnLKHBHn3" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "PDAF only distribute one ensemble member of state vector to the model from `init_ens_pdaf`. The next ensemble member will be distributed by PDAF once it gets the state vector for the DA step. For example, if we need to perform DA at time step $k$ with $N_e$ ensemble members:\n", + "```\n", + "for i in range(Ne):\n", + " - PDAF distribute the i-th ensemble member to the model at time step 0.\n", + " - model performs forecast to k-th time step\n", + " - PDAF collects the i-th ensemble member at k-th step\n", + " - Users need to reset the model time step to 0.\n", + "PDAF perform DA., after all ensemble members are collected at time step k.\n", + "```" + ], + "metadata": { + "id": "BAmzujHhBJ5-" + } + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "_5L5eR_B6ZVq" + }, + "outputs": [], + "source": [ + "class PdafDistributor(PdafDistributor):\n", + " def distribute_state(self, dim_p, state_p):\n", + " \"\"\"PDAF will distribute state vector (state_p) to model field\n", + " \"\"\"\n", + " self.field = state_p[:].reshape((self.ny, self.nx))\n", + " return state_p" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "uzC5mODK6fxJ" + }, + "source": [ + "In this simple model example, there are no need for actual processing of the ensemble. Therefore, we only show screen output of root mean squared error based on sampled variance." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "A1lgaGqK6k7h" + }, + "outputs": [], + "source": [ + "class PdafDistributor(PdafDistributor):\n", + " def initial_process(self, step, dim_p, dim_ens, dim_ens_l, dim_obs_p, state_p, uinv, ens_p, flag):\n", + " \"\"\"initial processing of the ensemble before it is distributed to model fields\n", + " \"\"\"\n", + " print (f'RMS error according to sampled variance: {np.sqrt(np.mean(np.var(ens_p, axis=1)))}')\n", + " return state_p, uinv, ens_p" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "w4h3TACpstgl" + }, + "source": [ + "When obtaining the initial ensemble, users also need to provide information about when do we do the next analysis based on the arrival of the new observations. In our case, we have observations for each time step, but we'd like to assimilate it every other time steps." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "DbmL_zvjYJaa" + }, + "outputs": [], + "source": [ + "class PdafDistributor(PdafDistributor):\n", + " def next_observation(self, stepnow, nsteps, doexit, time):\n", + " # next observation will arrive at `nsteps' step\n", + " nsteps = 2\n", + " # doexit = 0 means that PDAF will continue to distribute state\n", + " # to model for further integrations\n", + " doexit = 0\n", + " # model time is not used here as we only use steps to define the time\n", + " return nsteps, doexit, time" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Bu157WPn7CiJ" + }, + "source": [ + "Here, we call `pyPDAF.init_foreacst` function where it executes our user-supplied functions. Here, the model obtains the first ensemble member and perform some initial preprocessing of the full ensemble given in `py_init_ens_pdaf`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "HX5TjUCNYTVh" + }, + "outputs": [], + "source": [ + "status = 0\n", + "distributor = PdafDistributor(nx, ny)\n", + "# loop over all dimensions\n", + "with pipes() as (out, err):\n", + " status = pyPDAF.init_forecast(distributor.next_observation,\n", + " distributor.distribute_state,\n", + " distributor.initial_process,\n", + " status)\n", + " print (out.read())\n", + "# put model variable in distributor back to model\n", + "field = distributor.field" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mGeTvOG2u8LU" + }, + "source": [ + "### Sequential data assimilation system\n", + "\n", + "Data assimilation combines the model forecast and the observations. Hence, to perform data assimilation, at each analysis step, PDAF must collect the new forecast from the model and read observations. The assimilation also needs a function that connects the forecast state to observations which usually is denoted as observation operator. To ensure the flexibility of the framework, these information depends on the user-supplied functions. This is because each observation type and model are different so one should expect the users can handle these information.\n", + "\n", + "In the serial system, the cycling can be divided into following steps:\n", + "1. model forecast using `step` function\n", + "2. put model forecast into PDAF state vector/ensemble array to perform DA using [`pyPDAF.assimilate`](https://yumengch.github.io/pyPDAF/_autosummary/pyPDAF.assimilate.html#pyPDAF.assimilate).\n", + "\n", + "In above steps, the model forecast function is implemented in [`step`](#Model) function.\n", + "\n", + "#### User-supplied functions for `pyPDAF.assimilate`\n", + "In the assimilation step, the two primary purposes is defined by `PdafCollector` and `Obs` classes. The `PdafCollector` class obtains the model forecast and the `Obs` will handle observations using the `Observation Module Infrastructure` in PDAF, a scheme to ease the difficulty in handling observations." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "q-lmJYuKLE4z" + }, + "outputs": [], + "source": [ + "class PdafCollector:\n", + " def __init__(self, nx, ny, field):\n", + " self.nx = nx\n", + " self.ny = ny\n", + " # define the model field based on the ensemble\n", + " self.field = field\n", + "\n", + "class Obs:\n", + " def __init__(self, i_obs):\n", + " # i_obs-th observations in the system starting from 1\n", + " self.i_obs = i_obs" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "PcPa7_IwLuFT" + }, + "source": [ + "##### Collecting forecast\n", + "Before going into the details of observation handling, we first\n", + "1. get functions that collects the model forecast [(`collect_state_pdaf`)](https://yumengch.github.io/pyPDAF/user_desc/py__collect_state_pdaf.html). Similar to `distribute_state_pdaf`, the state vector is collected for each ensemble member from model field.\n", + "2. preprocess the ensemble forecast before the data assimilation. In the pre-processing step, we calculate the forecast error and save the forecast ensemble. This is the last step before assimilation so it could help us understand the raw forecast data. In the pre-process, the `step` argument is negative\n", + "3. post-process the analysis ensemble after the assimilation. In this case, the `step` argument is positive." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "sbv-1b7GsxU1" + }, + "outputs": [], + "source": [ + "class PdafCollector(PdafCollector):\n", + " def collect_state(self, dim_p, state_p):\n", + " \"\"\"PDAF will collect state vector (state_p) from model field\n", + " \"\"\"\n", + " state_p[:] = self.field.ravel()\n", + " return state_p\n", + "\n", + " def preprocess(self, step, dim_ens, ens_p):\n", + " \"\"\"preprocessing of the ensemble before it is used by DA algorithms\n", + " \"\"\"\n", + " print (f'Forecast RMS error according to sampled variance: {np.sqrt(np.mean(np.var(ens_p, axis=1)))}')\n", + " for i in range(dim_ens):\n", + " np.savetxt(os.path.join('outputs', f'ens_{i+1}_step{-step}_for.txt') , ens_p[:, i].reshape((self.ny, self.nx)) )\n", + "\n", + " def postprocess(self, step, dim_ens, ens_p):\n", + " \"\"\"post-processing of the ensemble before it is distributed to model fields\n", + " \"\"\"\n", + " print (f'Analysis RMS error according to sampled variance: {np.sqrt(np.mean(np.var(ens_p, axis=1)))}')\n", + " for i in range(dim_ens):\n", + " np.savetxt(os.path.join('outputs', f'ens_{i+1}_step{step}_ana.txt' ), ens_p[:, i].reshape((self.ny, self.nx)) )\n", + "\n", + " def prepostprocess(self, step, dim_p, dim_ens, dim_ens_p, dim_obs_p, state_p, uinv, ens_p, flag):\n", + " if step < 0:\n", + " self.preprocess(step, dim_ens, ens_p)\n", + " else:\n", + " self.postprocess(step, dim_ens, ens_p)\n", + " return state_p, uinv, ens_p\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "1N-wjlkH3fSp" + }, + "source": [ + "##### Handling observations\n", + "Another essential ingredient of data assimilation is observation. Here, user-supplied functions give all information about the observations to PDAF. We use the OMI scheme in PDAF to handle observations. Without any localisations, only two user-supplied functions are required with the OMI scheme.\n", + "\n", + "Before we use the OMI scheme, we need to provide the number of observation types by [`pyPDAF.PDAFomi.init`](https://yumengch.github.io/pyPDAF/_autosummary/pyPDAF.PDAFomi.init.html#pyPDAF.PDAFomi.init). This function\n", + "\n", + "Here, we use only one type of observations." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "1YiHIwd7tDHW" + }, + "outputs": [], + "source": [ + "pyPDAF.PDAFomi.init(1)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yIExW3FhspP9" + }, + "source": [ + "In this very simple example, the OMI observation functions may look a bit verbose, but it can be useful for more complex systems.\n", + "\n", + "The OMI has four mandatory properties:\n", + "- [`doassim`](https://yumengch.github.io/pyPDAF/_autosummary/pyPDAF.PDAFomi.set_doassim.html#pyPDAF.PDAFomi.set_doassim): whether this observation is assimilated. If `doassim = 1`, this observation will be assimilated. If `doassim = 0`, it will not be assimilated.\n", + "- [`disttype`](https://yumengch.github.io/pyPDAF/_autosummary/pyPDAF.PDAFomi.set_disttype.html#pyPDAF.PDAFomi.set_disttype): In localisation, how do we calculate the distance between grid points? e.g., Cartesian, geographic, or great circle distance on a sphere. We do not use localisation in this example, but we still have to provide this option.\n", + "- [`ncoord`](https://yumengch.github.io/pyPDAF/_autosummary/pyPDAF.PDAFomi.set_ncoord.html#pyPDAF.PDAFomi.set_ncoord): Number of coordinates used for computation in localisation. In our example, as we have a 2D domain, the number should be 2.\n", + "- [`id_obs_p`](https://yumengch.github.io/pyPDAF/_autosummary/pyPDAF.PDAFomi.set_id_obs_p.html#pyPDAF.PDAFomi.set_id_obs_p): Indices of observed field in state vector. This is a 2D array that should have the same length as the observector vector for each dimension. If the observations do not need interpolation (e.g., observations are co-located with model grid points), the first dimension is 1. In this case, if the i-th observation is at the j-th element of the state vector, the i-th element of `id_obs_p` is `j`. If interpolation is needed, each dimension is the adjacent model grid points.\n", + "\n", + "In Fortran, these properties can be given to derived type `obs_f`. In the pyPDAF, setter functions are provided. In the [`pyPDAF.PDAFomi.gather_obs`](https://yumengch.github.io/pyPDAF/_autosummary/pyPDAF.PDAFomi.gather_obs.html#pyPDAF.PDAFomi.gather_obs) function, PDAFomi collects\n", + "- the observation vector\n", + "- error variance\n", + "- the spatial coordinate of the observations\n", + "\n", + "This function also returns the dimension of the observation for given observation type." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "r-7PUdExu6FO" + }, + "outputs": [], + "source": [ + "class Obs(Obs):\n", + " def init_dim(self, step, dim_obs):\n", + " # We always assimilate the observation\n", + " pyPDAF.PDAFomi.set_doassim(self.i_obs, 1)\n", + " # Type of distance computation to use for localization\n", + " # It is mandatory for OMI even if we don't use localisation\n", + " pyPDAF.PDAFomi.set_disttype(self.i_obs, 0)\n", + " # Number of coordinates use for distance computation\n", + " pyPDAF.PDAFomi.set_ncoord(self.i_obs, 2)\n", + "\n", + " # read observations\n", + " obs = np.loadtxt(os.path.join('inputs_online', f'obs_step{step}.txt'))\n", + " # get the dimension of the model grid\n", + " ny, nx = obs.shape\n", + " # flatten the observations\n", + " obs = obs.ravel()\n", + " # a mask for observed gridpoints\n", + " condition = np.logical_not(np.isclose(obs, -999))\n", + "\n", + " # observation vector\n", + " y = obs[condition]\n", + "\n", + " # The relationship between observation and state vector\n", + " # we only have 28 osbervations and each observation corresponds to\n", + " # the grid point of one element in the state vector\n", + " # id_obs_p gives the indices of observed field in state vector\n", + " # the id starts from 1\n", + " # ensure 2D arryas are in Fortran order\n", + " id_obs_p = np.zeros((1, len(y)), dtype=np.intc, order='F')\n", + " id_obs_p[0] = np.arange(1, len(obs) + 1, dtype=np.intc)[condition]\n", + " pyPDAF.PDAFomi.set_id_obs_p(self.i_obs, 1, len(y), id_obs_p)\n", + "\n", + " # inverse of observation variance\n", + " ivar_obs_p = 1./0.5/0.5*np.ones_like(y)\n", + "\n", + " # coordinate of each observations\n", + " ocoord_p = np.zeros((2, len(y)), order='F')\n", + " ocoord_p[0] = np.tile(np.arange(nx), ny)[condition]\n", + " ocoord_p[1] = np.repeat(np.arange(ny), nx)[condition]\n", + "\n", + " # not being used here, only used for localisation\n", + " local_range = 0.\n", + " dim_obs = pyPDAF.PDAFomi.gather_obs(self.i_obs, len(y), y,\n", + " ivar_obs_p, ocoord_p, 2, local_range)\n", + " return dim_obs" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dXejHv4bl9qp" + }, + "source": [ + "The other user-supplied function in this example will be the observation operator. In this simple example, the state vector in the observation space can be conveniently obtained by the OMI function [`pyPDAF.PDAFomi.obs_op_gridpoint`](https://yumengch.github.io/pyPDAF/_autosummary/pyPDAF.PDAFomi.obs_op_gridpoint.html#pyPDAF.PDAFomi.obs_op_gridpoint) using the information provided in the `init_dim_obs` function. This function provides an observation operator where observations are located on the model grid points. When observations are not located on model grid points, PDAFomi also provides functions using linear interpolations on various grid. In this case, one may need to refer to [PDAF documentation](https://pdaf.awi.de/trac/wiki/OMI_observation_operators#Initializinginterpolationcoefficients) and [`id_obs_p` doc](https://yumengch.github.io/pyPDAF/_autosummary/pyPDAF.PDAFomi.set_id_obs_p.html#pyPDAF.PDAFomi.set_id_obs_p) for a better explanation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "DBfL7xBQl-Nt" + }, + "outputs": [], + "source": [ + "class Obs(Obs):\n", + " def op(self, step, dim_p, dim_obs_p, state_p, ostate):\n", + " \"\"\"observation operator\n", + " \"\"\"\n", + " return pyPDAF.PDAFomi.obs_op_gridpoint(self.i_obs, state_p, ostate)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "V3V8ogKsh8Nq" + }, + "source": [ + "##### Forward loop\n", + "\n", + "Now, we can write code for the sequential DA system using [`pyPDAF.assimilate`](https://yumengch.github.io/pyPDAF/_autosummary/pyPDAF.assimilate.html#pyPDAF.assimilate). This function is universal for all available filters in PDAF that use diagnoal observation error covariance matrix. Hence, it asks for a few user-supplied functions that are meant to be used for domain localisation. In this tutorial, we can simply provide dummy functions here." + ] + }, + { + "cell_type": "code", + "source": [ + "def init_n_domains_p_pdaf(): pass\n", + "def init_dim_l_pdaf(): pass\n", + "def init_dim_obs_l_pdaf(): pass" + ], + "metadata": { + "id": "6l-TS8gtgL--" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "51H_l8TuwSBk" + }, + "outputs": [], + "source": [ + "os.makedirs('outputs', exist_ok=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "PIz-l6zaZMNo" + }, + "outputs": [], + "source": [ + "# create directory to\n", + "current_step = 0\n", + "steps_for = 2\n", + "# get model field distributed by PDAF from `init_forecast`\n", + "field = distributor.field\n", + "obs = Obs(1)\n", + "# full DA system integration loop\n", + "while current_step < nsteps:\n", + "\n", + " for i in range(dim_ens):\n", + " # model integration\n", + " if i == dim_ens - 1: print('start DA')\n", + " for _ in range(steps_for):\n", + " field = step(field)\n", + "\n", + " # PDAF does assimilation\n", + " with pipes() as (out, err):\n", + " collector = PdafCollector(nx, ny, field)\n", + " status = pyPDAF.assimilate(collector.collect_state,\n", + " distributor.distribute_state,\n", + " obs.init_dim, obs.op,\n", + " init_n_domains_p_pdaf,\n", + " init_dim_l_pdaf, init_dim_obs_l_pdaf,\n", + " collector.prepostprocess,\n", + " distributor.next_observation, status)\n", + " s = out.read()\n", + " print (s)\n", + " field = distributor.field\n", + " current_step += steps_for" + ] + }, + { + "cell_type": "markdown", + "source": [ + "The above loop is for illustration purpose of the serial model forecast, collection and distribution of state vector of an ensemble. One can also perform ensemble DA with a single process with assisted function [`pyPDAF.get_fcst_info`](https://yumengch.github.io/pyPDAF/_autosummary/pyPDAF.get_fcst_info.html#pyPDAF.get_fcst_info), e.g.,\n", + "```Python\n", + "doexit = 0\n", + "while True:\n", + " if doexit == 1: break\n", + " for _ in range(steps_for):\n", + " field = step(field)\n", + "\n", + " # PDAF does assimilation\n", + " with pipes() as (out, err):\n", + " status = pyPDAF.assimilate(collector.collect_state,\n", + " distributor.distribute_state,\n", + " obs.init_dim, obs.op,\n", + " init_n_domains_p_pdaf,\n", + " init_dim_l_pdaf, init_dim_obs_l_pdaf,\n", + " collector.prepostprocess,\n", + " distributor.next_observation, status)\n", + " s = out.read()\n", + " print (s)\n", + "\n", + " steps_for, time, doexit = pyPDAF.get_fcst_info(steps_for, time, doexit)\n", + "```" + ], + "metadata": { + "id": "iy8s9GdXqTkc" + } + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8Jh6AZbX6VO0" + }, + "source": [ + "## Finalise PDAF\n", + "\n", + "At the end of the data assimilation program, one should finalise the PDAF system using [`pyPDAF.PDAF.deallocate`](https://yumengch.github.io/pyPDAF/_autosummary/pyPDAF.PDAF.deallocate.html#pyPDAF.PDAF.deallocate). One can also obtain screen output of the computational time and memory use information using [pyPDAF.PDAF.print_info](https://yumengch.github.io/pyPDAF/_autosummary/pyPDAF.PDAF.print_info.html#pyPDAF.PDAF.print_info)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "ntkle5Ah6VO0" + }, + "outputs": [], + "source": [ + "with pipes() as (out, err):\n", + " pyPDAF.deallocate()\n", + " pyPDAF.PDAF.print_info(1)\n", + "print (out.read())" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kTBiN9NAR1M1" + }, + "source": [ + "### Does analysis look better than forecast?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "0qoAUD5-R0BH" + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "from matplotlib import animation\n", + "import numpy as np\n", + "from IPython.display import HTML\n", + "dim_ens=9\n", + "ny, nx = 18, 36\n", + "# define diagnotics and model fields\n", + "spread = {'fcst': np.zeros(9), 'ana': np.zeros(9)}\n", + "RMSE = {'fcst': np.zeros(9), 'ana': np.zeros(9)}\n", + "field = {'truth': np.zeros((ny, nx)),\n", + " 'fcst': np.zeros((dim_ens, ny, nx)),\n", + " 'ana': np.zeros((dim_ens, ny, nx))\n", + " }\n", + "for key in spread:\n", + " spread[key][:] = np.nan\n", + " RMSE[key][:] = np.nan\n", + "# time\n", + "time = np.arange(2, 20, 2)\n", + "\n", + "# get figure\n", + "fig = plt.figure('err')\n", + "w, h = fig.get_size_inches()\n", + "fig.set_size_inches(2*w, 2*h)\n", + "# define the time series plot\n", + "ax = fig.add_subplot(212)\n", + "ax.set_title('Time series of the ensemble spread and RMSE')\n", + "ax.set_ylim([0., 1.2])\n", + "ax.set_xlim([time[0] - 1, time[-1] + 1])\n", + "lines = []\n", + "for key, c in zip(spread, ['k', 'r']):\n", + " line, = ax.plot(time, spread[key], color=c, linestyle='dashed',label=f'{key} spread')\n", + " lines.append(line)\n", + " line, = ax.plot(time, RMSE[key], color=c, linestyle='solid',label=f'{key} RMSE')\n", + " lines.append(line)\n", + "ax.legend()\n", + "# define pcolormesh plots\n", + "ax = {'fcst': fig.add_subplot(221), 'ana': fig.add_subplot(222),}\n", + "pc = dict()\n", + "for key in ax:\n", + " pc[key] = ax[key].pcolormesh(field[key].mean(0) - field['truth'],\n", + " cmap='coolwarm', vmin=-.06, vmax=.06)\n", + " fig.colorbar(pc[key], ax=ax[key])\n", + "\n", + "def draw_error(i):\n", + " \"\"\"Draw error at each analysis time step\n", + " \"\"\"\n", + " field['truth'] = np.loadtxt(os.path.join('inputs_online', f'true_step{i}.txt'))\n", + " for j in range(1, dim_ens + 1):\n", + " field['fcst'][j-1] = np.loadtxt(os.path.join('outputs', f'ens_{j}_step{i}_for.txt'))\n", + " field['ana'][j-1] = np.loadtxt(os.path.join('outputs', f'ens_{j}_step{i}_ana.txt'))\n", + "\n", + " for j, key in enumerate(spread):\n", + " spread[key][i//2 - 1] = field[key].std(0).mean()\n", + " RMSE[key][i//2 - 1] = np.sqrt(np.mean((field[key].mean(0) - field['truth'])**2))\n", + " lines[2*j].set_ydata(spread[key])\n", + " lines[2*j + 1].set_ydata(RMSE[key])\n", + "\n", + " for key in ax:\n", + " ax[key].set_title(f'{key} error ({np.round(RMSE[key][i//2 - 1], 3)})')\n", + " pc[key].set_array(field[key].mean(0) - field['truth'])\n", + "\n", + " return pc['fcst'], pc['ana'], *lines\n", + "\n", + "# make an animation\n", + "anim = animation.FuncAnimation(fig, draw_error, frames=time, interval=1000, blit=True)\n", + "plt.close(fig)\n", + "HTML(anim.to_html5_video())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "e3UapHAi6VO0" + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "colab": { + "provenance": [], + "collapsed_sections": [ + "lSsjNPl-F1On", + "b-mYku6H84ud" + ] + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.1" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file