diff --git a/.github/workflows/_build_and_publish_documentation.yml b/.github/workflows/_build_and_publish_documentation.yml
index 3f39aa7..8df022f 100644
--- a/.github/workflows/_build_and_publish_documentation.yml
+++ b/.github/workflows/_build_and_publish_documentation.yml
@@ -13,20 +13,16 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout active branch
- uses: actions/checkout@v4
+ uses: actions/checkout@v5
with:
lfs: true
- name: Install uv
- uses: astral-sh/setup-uv@v5
+ uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- cache-dependency-glob: "uv.lock"
- - name: Set up Python
- uses: actions/setup-python@v5
- with:
- python-version-file: "pyproject.toml"
+ cache-dependency-glob: 'uv.lock'
- name: Install the project
- run: uv sync --upgrade
+ run: uv sync --frozen
- name: Print debugging information
run: |
echo "github.ref:" ${{github.ref}}
diff --git a/.github/workflows/_build_package.yml b/.github/workflows/_build_package.yml
index 5c21af4..509ec20 100644
--- a/.github/workflows/_build_package.yml
+++ b/.github/workflows/_build_package.yml
@@ -7,23 +7,23 @@ jobs:
name: Build source distribution
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - name: Checkout code
+ uses: actions/checkout@v5
with:
lfs: true
- name: Install uv
- uses: astral-sh/setup-uv@v5
+ uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- cache-dependency-glob: "uv.lock"
- - uses: actions/setup-python@v5
- with:
- python-version-file: "pyproject.toml"
- - name: Build source distribution and wheel
+ cache-dependency-glob: 'uv.lock'
+ - name: Build source distribution and wheels
run: uv build
- - name: Run twine check
+ - name: Check build artifacts
run: uvx twine check --strict dist/*
- - uses: actions/upload-artifact@v4
+ - name: Upload build artifacts
+ uses: actions/upload-artifact@v5
with:
+ name: dist
path: |
dist/*.tar.gz
dist/*.whl
diff --git a/.github/workflows/_code_quality.yml b/.github/workflows/_code_quality.yml
index 3ef1e81..6d7f696 100644
--- a/.github/workflows/_code_quality.yml
+++ b/.github/workflows/_code_quality.yml
@@ -7,18 +7,15 @@ jobs:
runs-on: ubuntu-latest
name: ruff format
steps:
- - uses: actions/checkout@v4
+ - name: Checkout code
+ uses: actions/checkout@v5
- name: Install uv
- uses: astral-sh/setup-uv@v5
+ uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- cache-dependency-glob: "uv.lock"
- - name: Set up Python
- uses: actions/setup-python@v5
- with:
- python-version-file: "pyproject.toml"
+ cache-dependency-glob: 'uv.lock'
- name: Install the project
- run: uv sync --upgrade
+ run: uv sync -U
- name: Run ruff format
run: uv run ruff format --diff
@@ -26,18 +23,15 @@ jobs:
runs-on: ubuntu-latest
name: ruff check
steps:
- - uses: actions/checkout@v4
+ - name: Checkout code
+ uses: actions/checkout@v5
- name: Install uv
- uses: astral-sh/setup-uv@v5
+ uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- cache-dependency-glob: "uv.lock"
- - name: Set up Python
- uses: actions/setup-python@v5
- with:
- python-version-file: "pyproject.toml"
+ cache-dependency-glob: 'uv.lock'
- name: Install the project
- run: uv sync --upgrade
+ run: uv sync -U
- name: Run ruff check
run: uv run ruff check --diff
@@ -45,18 +39,15 @@ jobs:
runs-on: ubuntu-latest
name: pyright
steps:
- - uses: actions/checkout@v4
+ - name: Checkout code
+ uses: actions/checkout@v5
- name: Install uv
- uses: astral-sh/setup-uv@v5
+ uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- cache-dependency-glob: "uv.lock"
- - name: Set up Python
- uses: actions/setup-python@v5
- with:
- python-version-file: "pyproject.toml"
+ cache-dependency-glob: 'uv.lock'
- name: Install the project
- run: uv sync --upgrade
+ run: uv sync -U
- name: Run pyright
run: uv run pyright
@@ -64,17 +55,14 @@ jobs:
runs-on: ubuntu-latest
name: mypy
steps:
- - uses: actions/checkout@v4
+ - name: Checkout code
+ uses: actions/checkout@v5
- name: Install uv
- uses: astral-sh/setup-uv@v5
+ uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- cache-dependency-glob: "uv.lock"
- - name: Set up Python
- uses: actions/setup-python@v5
- with:
- python-version-file: "pyproject.toml"
+ cache-dependency-glob: 'uv.lock'
- name: Install the project
- run: uv sync --upgrade
+ run: uv sync -U
- name: Run mypy
run: uv run mypy
diff --git a/.github/workflows/_merge_into_release.yml b/.github/workflows/_merge_into_release.yml
index cec3964..67348de 100644
--- a/.github/workflows/_merge_into_release.yml
+++ b/.github/workflows/_merge_into_release.yml
@@ -12,7 +12,8 @@ jobs:
runs-on: ubuntu-latest
environment: release
steps:
- - uses: actions/checkout@v4
+ - name: Checkout code
+ uses: actions/checkout@v5
with:
# Fetch the whole history to prevent unrelated history errors
fetch-depth: 0
diff --git a/.github/workflows/_test.yml b/.github/workflows/_test.yml
index 5a43734..ab2de79 100644
--- a/.github/workflows/_test.yml
+++ b/.github/workflows/_test.yml
@@ -4,33 +4,23 @@ on: workflow_call
jobs:
test:
- name: Test on ${{matrix.python.version}}-${{matrix.platform.runner}}
- runs-on: ${{ matrix.platform.runner }}
+ name: Test (Python ${{ matrix.python }}, ${{ matrix.os }})
+ runs-on: ${{ matrix.os }}
strategy:
- fail-fast: true
+ fail-fast: false
matrix:
- platform:
- - runner: ubuntu-latest
- - runner: windows-latest
- # - runner: macos-latest
- python:
- - version: '3.10'
- - version: '3.11'
- - version: '3.12'
- # - version: '3.13'
+ os: [ubuntu-latest, windows-latest]
+ python: ['3.11', '3.12', '3.13', '3.14']
steps:
- - uses: actions/checkout@v4
+ - name: Checkout code
+ uses: actions/checkout@v5
- name: Install uv
- uses: astral-sh/setup-uv@v5
+ uses: astral-sh/setup-uv@v7
with:
- enable-cache: false
- cache-dependency-glob: "uv.lock"
- - name: Install Python ${{ matrix.python.version }}
- uses: actions/setup-python@v5
- with:
- python-version: ${{ matrix.python.version }}
+ enable-cache: true
+ cache-dependency-glob: 'uv.lock'
- name: Install the project
- run: uv sync -p ${{ matrix.python.version }} -U --no-dev
+ run: uv sync -p ${{ matrix.python }} -U --no-dev --extra test
- name: Run pytest
run: >
uv run --with pytest --with pytest-cov
diff --git a/.github/workflows/_test_future.yml b/.github/workflows/_test_future.yml
index 5f8e729..30f1d98 100644
--- a/.github/workflows/_test_future.yml
+++ b/.github/workflows/_test_future.yml
@@ -1,34 +1,41 @@
-name: Unit Tests (py313)
-# Test also with Python 3.13 (experimental; workflow will not fail on error.)
+name: Unit Tests (py315)
+# Test also with Python 3.15 (experimental; workflow will not fail on error.)
on: workflow_call
jobs:
- test313:
- name: Test on ${{matrix.python.version}}-${{matrix.platform.runner}} (experimental)
+ test315:
+ name: Test (Python ${{ matrix.python.version }}, ${{ matrix.os }}) (experimental)
continue-on-error: true
- runs-on: ${{ matrix.platform.runner }}
+ runs-on: ${{ matrix.os }}
strategy:
+ fail-fast: true
matrix:
- platform:
- - runner: ubuntu-latest
- - runner: windows-latest
+ os: [ubuntu-latest, windows-latest]
python:
- - version: '3.13.0-alpha - 3.13.0'
- uvpy: '3.13'
+ - version: '3.15.0-alpha - 3.15.0'
+ uvpy: '3.15'
steps:
- - uses: actions/checkout@v4
+ - name: Checkout code
+ uses: actions/checkout@v5
- name: Install uv
- uses: astral-sh/setup-uv@v5
+ uses: astral-sh/setup-uv@v7
with:
- enable-cache: false
- cache-dependency-glob: "uv.lock"
- - name: Install Python ${{ matrix.python.version }}
- uses: actions/setup-python@v5
- with:
- python-version: ${{ matrix.python.version }}
+ enable-cache: true
+ cache-dependency-glob: 'uv.lock'
+ - name: Remove Python upper version constraint from pyproject.toml
+ shell: pwsh
+ run: |
+ $File = Get-Item pyproject.toml
+ $Content = Get-Content $File -Raw
+ [regex]$RequiresPythonPattern = '(?=]{1,2}\s?\d+\.\d+\.?\d*\.?[\d\w]*\s?)(,\s?[<=]{1,2}\s?\d+\.?\d*\.?\d*\.?[\d\w]*\s?)?(")'
+ if ($Content -match $RequiresPythonPattern) {
+ $RequiresPythonFound = $Matches[0]
+ $RequiresPythonReplacement = $Matches[1] + $Matches[3]
+ $Content -Replace $RequiresPythonFound, $RequiresPythonReplacement | Set-Content $File -NoNewline
+ }
- name: Install the project
- run: uv sync -p ${{ matrix.python.uvpy }} -U --no-dev
+ run: uv sync -p ${{ matrix.python.uvpy }} -U --no-dev --extra test
- name: Run pytest
run: >
uv run --with pytest --with pytest-cov
diff --git a/.github/workflows/nightly_build.yml b/.github/workflows/nightly_build.yml
index 28f6868..41eb2a2 100644
--- a/.github/workflows/nightly_build.yml
+++ b/.github/workflows/nightly_build.yml
@@ -4,10 +4,9 @@ run-name: Nightly Build (by @${{ github.actor }})
on:
schedule:
- cron: '30 5 * * *'
+ workflow_dispatch: # Allow manual trigger
jobs:
- code_quality:
- uses: ./.github/workflows/_code_quality.yml
test:
uses: ./.github/workflows/_test.yml
test_future:
diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml
index faff098..bd97143 100644
--- a/.github/workflows/publish_release.yml
+++ b/.github/workflows/publish_release.yml
@@ -18,11 +18,13 @@ jobs:
permissions:
id-token: write
steps:
- - uses: actions/download-artifact@v4
+ - name: Download build artifacts
+ uses: actions/download-artifact@v5
with:
- name: artifact
+ name: dist
path: dist
- - uses: pypa/gh-action-pypi-publish@release/v1
+ - name: Publish to PyPI
+ uses: pypa/gh-action-pypi-publish@release/v1
# with: # Uncomment this line to publish to testpypi
# repository-url: https://test.pypi.org/legacy/ # Uncomment this line to publish to testpypi
merge_into_release:
diff --git a/.github/workflows/pull_request_to_main.yml b/.github/workflows/pull_request_to_main.yml
index 2bff438..1e73c39 100644
--- a/.github/workflows/pull_request_to_main.yml
+++ b/.github/workflows/pull_request_to_main.yml
@@ -11,6 +11,7 @@ on:
- converted_to_draft
branches:
- main
+ workflow_dispatch: # Allow manual trigger
concurrency:
group: pr-${{ github.ref }}-1
diff --git a/.gitignore b/.gitignore
index 71b7e79..23efa9a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -91,7 +91,7 @@ ipython_config.py
# It is generally recommended to include `uv.lock` in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, `uv` might install dependencies in one environment that don't work in another.
-# In such case, `uv.lock` should be added to `.gitignore`
+# In such case, `uv.lock` should be added to `.gitignore` (and, as such, excluded from version control).
# uv.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index df75480..c7ca41c 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v5.0.0
+ rev: v6.0.0
hooks:
- id: mixed-line-ending
args: [--fix=auto]
@@ -9,10 +9,10 @@ repos:
- id: check-toml
- id: check-merge-conflict
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: v0.9.2
+ rev: v0.15.1
hooks:
- id: ruff-format
- - id: ruff
+ - id: ruff-check
# - repo: https://github.com/pre-commit/mirrors-mypy
# rev: v1.14.1
# hooks:
diff --git a/.sourcery.yaml b/.sourcery.yaml
index 875292b..5b5817f 100644
--- a/.sourcery.yaml
+++ b/.sourcery.yaml
@@ -30,7 +30,7 @@ rule_settings:
- refactoring
- suggestion
- comment
- python_version: '3.10' # A string specifying the lowest Python version your project supports. Sourcery will not suggest refactorings requiring a higher Python version.
+ python_version: '3.11' # A string specifying the lowest Python version your project supports. Sourcery will not suggest refactorings requiring a higher Python version.
# rules: # A list of custom rules Sourcery will include in its analysis.
# - id: no-print-statements
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index 2accaf5..d6549af 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -5,8 +5,9 @@
"recommendations": [
"ms-python.python",
"ms-python.vscode-pylance",
- "visualstudioexptteam.vscodeintellicode",
- "njqdev.vscode-python-typehint",
+ "github.copilot-chat",
+ "ms-python.debugpy",
+ "ms-python.vscode-python-envs",
"charliermarsh.ruff",
"sourcery.sourcery",
"njpwerner.autodocstring",
diff --git a/.vscode/launch.json b/.vscode/launch.json
index fd2a677..df630c6 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -19,7 +19,11 @@
"autoReload": {
"enable": true
},
+ "subProcess": true,
"justMyCode": true,
+ "redirectOutput": true, // pipe stdout/stderr to Debug Console
+ "showReturnValue": true,
+ "logToFile": false, // set true temporarily when diagnosing debugger issues
},
{
"name": "Python: Current File, cwd = file dir",
@@ -28,10 +32,14 @@
"cwd": "${fileDirname}", // working dir = dir where current file is
"program": "${file}",
"console": "integratedTerminal",
- "justMyCode": true,
"autoReload": {
"enable": true
},
+ "subProcess": true,
+ "justMyCode": true,
+ "redirectOutput": true,
+ "showReturnValue": true,
+ "logToFile": false,
},
{
"name": "Python: Current File, cwd = workspace root folder",
@@ -43,14 +51,18 @@
"autoReload": {
"enable": true
},
+ "subProcess": true,
"justMyCode": true,
+ "redirectOutput": true,
+ "showReturnValue": true,
+ "logToFile": false,
},
{
"name": "sim_explorer test_cli",
"type": "debugpy",
"request": "launch",
"cwd": "${workspaceFolder}\\tests",
- "program": "${workspaceFolder}\\src\\sim_explorer\\cli\\sim_explorer.py",
+ "program": "${workspaceFolder}\\src\\sim_explorer\\cli\\__main__.py",
"args": [
"test_config_file",
"--run",
@@ -60,7 +72,11 @@
"autoReload": {
"enable": true
},
+ "subProcess": true,
"justMyCode": true,
+ "redirectOutput": true,
+ "showReturnValue": true,
+ "logToFile": false,
},
]
}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 8ec2fac..efe9d30 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -46,7 +46,7 @@
},
],
"mypy-type-checker.importStrategy": "fromEnvironment",
- "mypy-type-checker.reportingScope": "workspace",
+ "mypy-type-checker.reportingScope": "custom",
"mypy-type-checker.preferDaemon": true,
"ruff.configurationPreference": "filesystemFirst",
-}
\ No newline at end of file
+}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6f5b5dc..a57bbfe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,7 +5,115 @@ The changelog format is based on [Keep a Changelog](https://keepachangelog.com/e
## [Unreleased]
--/-
+* -/-
+
+
+## [0.2.2] - 2026-03-04
+
+### Resolved
+* src/sim_explorer/__init__.py: Added `import libcosimpy.CosimLibrary` in `__init__.py` on package root level. This to make sure the libcosimc dll gets loaded only once. This resolves a runtime error observed with libcosimpy. (Although the root bug is likely in libcosimpy; should be reviewed by the libcosimpy team).
+
+### Added
+* Added a new module `codegen.py` in sub-package `utils`, defining a helper function `get_callable_function()`:
+ * `get_callable_function()` executes compiled code in explicit namespaces, retrieves a named function, validates it is callable, and eventually returns the created function.
+ * Refactored class `Assertion` in module `assertion.py` to use the new helper function `get_callable_function()`. That way, the code in `Assertion` no longer relies on mutating `locals()`, which is known to be unreliable and can cause hard-to-track side effects.
+ * Updated the related tests in `tests/test_assertion.py`.
+
+### Removed
+* Removed qa.bat
+* Removed \_\_init\_\_.py files in /tests
+
+### Changed
+* GitHub Workflows:
+ * _test_future.yml: Updated Python version in test_future to 3.15.0-alpha - 3.15.0
+ * _test.yml: Updated Python versions in test matrix to 3.11, 3.12, 3.13, 3.14
+ * Added 'name: Checkout code' to uses of 'actions/checkout', for better readability and consistency across workflow files.
+ * Added 'name: Download build artifacts' to uses of 'actions/download-artifact', for better readability and consistency across workflow files.
+ * Added 'name: Publish to PyPI' to uses of 'pypa/gh-action-pypi-publish', for better readability and consistency across workflow files.
+ * Added 'name: Upload build artifacts' to uses of 'actions/upload-artifact', for better readability and consistency across workflow files.
+ * Changed 'uv sync --upgrade' to 'uv sync -U'
+ * Ensured that actions 'upload-artifact' and 'download-artifact' uniformly specify 'dist' as (file)name for the artifact uploaded (or downloaded, respectively), for consistency across workflow files.
+ * pull_request_to_main.yml and nightly_build.yml: Added 'workflow_dispatch:' in selected workflows to allow manual trigger of the workflow.
+ * Removed redundant 'Set up Python' steps (no longer needed, as 'uv sync' will automatically install Python if not present).
+ * Replaced 'Build source distribution and wheel' with 'Build source distribution and wheels' (plural) in workflow step names.
+ * Replaced 'Run twine check' with 'Check build artifacts' in workflow step names, to better reflect the purpose of the step.
+ * Updated the syntax used for the OS and Python matrix in test workflows.
+ * Added `--extra test` to the workflows running tests, as the test workflows will need these additional dependencies to run the FMUs in /tests/data/..
+* pyproject.toml:
+ * Added required-environments to uv.tools (windows, linux)
+ * Removed deprecated mypy plugin 'numpy.typing.mypy_plugin'
+ * Removed deprecated pyright setting 'reportShadowedImports'
+ * Removed leading carets and trailing slashes from 'exclude' paths
+ * Removed trailing slashes from 'exclude' paths
+ * Updated supported Python versions to 3.11, 3.12, 3.13, 3.14
+ * Removed upper version constraint from required Python version, i.e. changed the "requires-python" field from ">= 3.11, < 3.15" to ">= 3.11".
+ Detailed background and reasoning in this good yet long post by Henry Schreiner:
+ https://iscinumpy.dev/post/bound-version-constraints/#pinning-the-python-version-is-special
+ TLDR: Placing an upper Python version constraint on a Python package causes more harm than it provides benefits.
+ The upper version constraint unnecessarily manifests incompatibility with future Python releases.
+ Removing the upper version constraint ensures the package remains installable as Python evolves.
+ In the majority of cases, the newer Python version will anyhow be backward-compatible. And in the rare case where your package would really not work with a newer Python version,
+ users can at least find a solution manually to resolve the conflict, e.g. by pinning your package to the last version compatible with the environment they install it in.
+ That way, we ensure it remains _possible_ for users to find a solution, instead of rendering it impossible forever.
+ * Added scipy>=1.16 to optional dependency group 'test', as TimeTableFMU.fmu requires scipy to be installed in the calling environment.
+ * Added default directories to the 'exclude' list for pyright, in section [tool.pyright]
+ (Ref note in pyright [docs](https://github.com/microsoft/pylance-release/blob/main/docs/settings/python_analysis_exclude.md#default-behavior)).
+* Sphinx Documentation:
+ * Sphinx conf.py: Removed ruff rule exception on file level
+ * Sphinx conf.py: Updated year in copyright statement to 2026
+* VS Code Settings:
+ * Recommended extensions:
+ * Removed 'njqdev.vscode-python-typehint' (Python Type Hint). Not maintained since 1 year, and the functionality is now covered by GitHub Copilot.
+ * Added 'ms-python.debugpy' (Python Debugger).
+ * Added 'ms-python.vscode-python-envs' (Python Environments).
+ * Removed deprecated IntelliCode extension and replaced it by GitHub Copilot Chat as recommended replacement.
+ * Updated 'mypy-type-checker.reportingScope' to 'custom'.
+* .pre-commit-config.yaml: Updated id of ruff to ruff-check
+* .sourcery.yaml: Updated the lowest Python version the project supports to '3.11'
+* ruff.toml: Updated target Python version to "py311"
+* src/sim_explorer/models.py:
+ * Renamed temporal operators `Temporal.FINALLY` to `Temporal.EVENTUALLY`, and adapted a related docstring in src/sim_explorer/assertion.py, to make clearer the meaning of the STL `EVENTUALLY` operator.
+
+### Tests
+* tests/data/BouncingBall3D: Updated `BouncingBall3D.fmu` and related tests.
+* tests/data/MobileCrane: Updated `MobileCrane.fmu` and related tests.
+* tests/data/Oscillator: Updated `HarmonicOscillator.fmu`
+* Renamed folder `tests/data/SimpleTable` to `tests/data/TimeTable`
+* Replaced `SimpleTable.fmu` with `TimeTableFMU.fmu` (in folder `tests/data/TimeTable`)
+* tests/conftest.py:
+ * Changed scope of top level fixtures from "package" to "session", because "session" scoped fixtures gets called before "package" scoped fixtures
+ * Changed the additional `pytest` command line option `--show` from an input option (requesting the user to pass a literal value, e.g. write `--show True` or `--show False` ) to a command line _switch_. This eases the usage of this additional command line option. The pytest fixture `show` now gets set to `True` by simply adding the switch `--show` on the commandline. No need anylonger to amend `--show` with an additional string literal `True` or `False`. Passing the switch `--show` sets fixture `show` to `True`; omitting it sets fixture `show` to `False`.
+* Repaired all failing tests
+
+### Dependencies
+* Updated to docutils>=0.22.4
+* Updated to furo>=2025.12
+* Updated to jupyter>=1.1.1
+* Updated to libcosimpy>=0.0.5
+* Updated to mypy>=1.19.1
+* Updated to myst-parser>=5.0
+* Updated to numpy>=2.3 (removed split version specifiers)
+* Updated to plotly>=6.5
+* Updated to pre-commit>=4.5
+* Updated to pydantic>=2.12
+* Updated to pyright>=1.1.408
+* Updated to pytest-cov>=7.0
+* Updated to pytest>=9.0
+* Updated to ruff>=0.15.1
+* Updated to sourcery>=1.43.0
+* Updated to sphinx>=9.0
+* Updated to sphinx-argparse-cli>=1.20.1
+* Updated to sphinx-autodoc-typehints>=3.6
+* Updated to sphinxcontrib-mermaid>=2.0
+* Updated to sympy>=1.14.0
+* .pre-commit-config.yaml:
+ * Updated rev of pre-commit-hooks to v6.0.0
+ * Updated rev of ruff-pre-commit to v0.15.1
+* GitHub Workflows:
+ * Updated 'checkout' action to v5
+ * Updated 'download-artifact' action to v5
+ * Updated 'setup-uv' action to v7
+ * Updated 'upload-artifact' action to v5
## [0.2.1] - 2025-02-05
@@ -97,7 +205,8 @@ New Assertions release:
-[unreleased]: https://github.com/dnv-opensource/sim-explorer/compare/v0.2.1...HEAD
+[unreleased]: https://github.com/dnv-opensource/sim-explorer/compare/v0.2.2...HEAD
+[0.2.2]: https://github.com/dnv-opensource/sim-explorer/releases/tag/v0.2.1...v0.2.2
[0.2.1]: https://github.com/dnv-opensource/sim-explorer/releases/tag/v0.2.0...v0.2.1
[0.2.0]: https://github.com/dnv-opensource/sim-explorer/releases/tag/v0.1.0...v0.2.0
[0.1.0]: https://github.com/dnv-opensource/sim-explorer/releases/tag/v0.0.1...v0.1.0
diff --git a/CITATION.cff b/CITATION.cff
index e9a355a..ab701dc 100644
--- a/CITATION.cff
+++ b/CITATION.cff
@@ -1,5 +1,5 @@
title: sim-explorer
-version: 0.2.1
+version: 0.2.2
abstract: >-
Experimentation tools on top of OSP simulation models.
type: software
@@ -13,7 +13,13 @@ authors:
- given-names: Siegfried
family-names: Eisinger
affiliation: DNV
- email: Siegfried.Eisinger@dnv.com
+ email: siegfried.eisinger@dnv.com
+ website: 'https://www.linkedin.com/in/siegfried-eisinger-a337638b'
+ - given-names: Jorge Luis
+ family-names: Mendez
+ affiliation: DNV
+ email: jorge.luis.mendez@dnv.com
+ website: 'https://www.linkedin.com/in/jorgelmh'
keywords:
- simulation
- model
diff --git a/LICENSE b/LICENSE
index 6e1652f..b009b9d 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2025 [DNV](https://www.dnv.com) [open source](https://github.com/dnv-opensource)
+Copyright (c) 2026 [DNV](https://www.dnv.com) [open source](https://github.com/dnv-opensource)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.rst b/README.rst
index 8f4bef0..7377765 100644
--- a/README.rst
+++ b/README.rst
@@ -1,22 +1,4 @@
-.. image:: https://img.shields.io/pypi/v/sim-explorer.svg?color=blue
- :target: https://pypi.org/project/sim-explorer
- :alt: pypi
-
-.. image:: https://img.shields.io/pypi/pyversions/sim-explorer.svg?color=blue
- :target: https://pypi.org/project/sim-explorer
- :alt: versions
-
-.. image:: https://img.shields.io/pypi/l/sim-explorer.svg
- :target: https://github.com/dnv-opensource/sim-explorer/blob/main/LICENSE
- :alt: license
-
-.. image:: https://img.shields.io/github/actions/workflow/status/dnv-opensource/sim-explorer/.github%2Fworkflows%2Fnightly_build.yml?label=ci
- :alt: ci
-
-.. image:: https://img.shields.io/github/actions/workflow/status/dnv-opensource/sim-explorer/.github%2Fworkflows%2Fpush_to_release.yml?label=docs
- :target: https://dnv-opensource.github.io/sim-explorer/README.html
- :alt: docs
-
+|pypi| |versions| |license| |ci| |docs|
Introduction
============
@@ -50,7 +32,9 @@ The package is currently under development. More instructions and documentation
Installation
------------
-``pip install sim-explorer``
+.. code:: sh
+
+ pip install sim-explorer
Development Setup
@@ -58,37 +42,47 @@ Development Setup
1. Install uv
^^^^^^^^^^^^^
-This project uses `uv` as package manager.
+This project uses ``uv`` as package manager.
If you haven't already, install `uv `_, preferably using it's `"Standalone installer" `_ method:
..on Windows:
-``powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"``
+.. code:: sh
+
+ powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
..on MacOS and Linux:
-``curl -LsSf https://astral.sh/uv/install.sh | sh``
+.. code:: sh
+
+ curl -LsSf https://astral.sh/uv/install.sh | sh
(see `docs.astral.sh/uv `_ for all / alternative installation methods.)
-Once installed, you can update `uv` to its latest version, anytime, by running:
+Once installed, you can update ``uv`` to its latest version, anytime, by running:
-``uv self update``
+.. code:: sh
+
+ uv self update
2. Install Python
^^^^^^^^^^^^^^^^^
-This project requires Python 3.10 or later.
+This project requires Python 3.11 or later.
If you don't already have a compatible version installed on your machine, the probably most comfortable way to install Python is through ``uv``:
-``uv python install``
+.. code:: sh
+
+ uv python install
This will install the latest stable version of Python into the uv Python directory, i.e. as a uv-managed version of Python.
Alternatively, and if you want a standalone version of Python on your machine, you can install Python either via ``winget``:
-``winget install --id Python.Python``
+.. code:: sh
+
+ winget install --id Python.Python
or you can download and install Python from the `python.org `_ website.
@@ -96,23 +90,39 @@ or you can download and install Python from the `python.org ``
+.. code:: sh
+
+ uv run
However, you still *can* manually activate the virtual environment if needed.
When developing in an IDE, for instance, this can in some cases be necessary depending on your IDE settings.
@@ -129,52 +141,69 @@ To manually activate the virtual environment, run one of the "known" legacy comm
..on Windows:
-``.venv\Scripts\activate.bat``
+.. code:: sh
+
+ .venv\Scripts\activate.bat
..on Linux:
-``source .venv/bin/activate``
+.. code:: sh
+
+ source .venv/bin/activate
6. Install pre-commit hooks
^^^^^^^^^^^^^^^^^^^^^^^^^^^
The ``.pre-commit-config.yaml`` file in the project root directory contains a configuration for pre-commit hooks.
To install the pre-commit hooks defined therein in your local git repository, run:
-``uv run pre-commit install``
+.. code:: sh
+
+ uv run pre-commit install
All pre-commit hooks configured in ``.pre-commit-config.yam`` will now run each time you commit changes.
pre-commit can also manually be invoked, at anytime, using:
-``uv run pre-commit run --all-files``
+.. code:: sh
+
+ uv run pre-commit run --all-files
-To skip the pre-commit validation on commits (e.g. when intentionally committing broken code), run:
+To skip the pre-commit validation on commits (e.g. when intentionally
+committing broken code), run:
-``uv run git commit -m --no-verify``
+.. code:: sh
-To update the hooks configured in `.pre-commit-config.yaml` to their newest versions, run:
+ uv run git commit -m --no-verify
-``uv run pre-commit autoupdate``
+To update the hooks configured in ``.pre-commit-config.yaml`` to their
+newest versions, run:
+
+.. code:: sh
+
+ uv run pre-commit autoupdate
7. Test that the installation works
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
To test that the installation works, run pytest in the project root folder:
-``uv run pytest``
+.. code:: sh
+ uv run pytest
Meta
----
-Copyright (c) 2024 `DNV `_ AS. All rights reserved.
+Copyright (c) 2026 `DNV `_ AS. All rights reserved.
-Siegfried Eisinger - siegfried.eisinger@dnv.com
+Siegfried Eisinger - `@LinkedIn `_ - siegfried.eisinger@dnv.com
+
+Jorge Luis Mendez - `@LinkedIn `_ - jorge.luis.mendez@dnv.com
Distributed under the MIT license. See `LICENSE `_ for more information.
`https://github.com/dnv-opensource/sim-explorer `_
-Contribute
-----------
+Contributing
+------------
Anybody in the OSP community is welcome to contribute to this code, to make it better,
and especially including other features from model assurance,
as we firmly believe that trust in our models is needed
@@ -191,4 +220,14 @@ To contribute, follow these steps:
6. Push to the branch (``git push origin issue-name``)
7. Create a new Pull Request in GitHub
-For your contribution, please make sure you follow the `STYLEGUIDE `_ before creating the Pull Request.
+For your contribution, please make sure you follow the `STYLEGUIDE `_ before creating the Pull Request.
+
+.. |pypi| image:: https://img.shields.io/pypi/v/sim-explorer.svg?color=blue
+ :target: https://pypi.python.org/pypi/sim-explorer
+.. |versions| image:: https://img.shields.io/pypi/pyversions/sim-explorer.svg?color=blue
+ :target: https://pypi.python.org/pypi/sim-explorer
+.. |license| image:: https://img.shields.io/pypi/l/sim-explorer.svg
+ :target: https://github.com/dnv-opensource/sim-explorer/blob/main/LICENSE
+.. |ci| image:: https://img.shields.io/github/actions/workflow/status/dnv-opensource/sim-explorer/.github%2Fworkflows%2Fnightly_build.yml?label=ci
+.. |docs| image:: https://img.shields.io/github/actions/workflow/status/dnv-opensource/sim-explorer/.github%2Fworkflows%2Fpush_to_release.yml?label=docs
+ :target: https://dnv-opensource.github.io/sim-explorer/README.html
diff --git a/docs/source/conf.py b/docs/source/conf.py
index e65baa2..915cf60 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -1,4 +1,3 @@
-# ruff: noqa
# mypy: ignore-errors
# Configuration file for the Sphinx documentation builder.
@@ -22,11 +21,11 @@
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
project = "sim-explorer"
-copyright = "2024, DNV AS. All rights reserved."
-author = "Siegfried Eisinger, DNV Simulation Technology Team, SEACo project team"
+copyright = "2026, DNV AS. All rights reserved."
+author = "Siegfried Eisinger, Jorge Luis Mendez, SEACo project team"
# The full version, including alpha/beta/rc tags
-release = "0.2.1"
+release = "0.2.2"
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
diff --git a/docs/source/sim_explorer.rst b/docs/source/sim_explorer.rst
index 2600a4d..55898ef 100644
--- a/docs/source/sim_explorer.rst
+++ b/docs/source/sim_explorer.rst
@@ -20,6 +20,10 @@ Modules
:template: custom-module.rst
:recursive:
+ sim_explorer.assertion
+ sim_explorer.case
+ sim_explorer.exceptions
sim_explorer.json5
+ sim_explorer.models
sim_explorer.system_interface
- sim_explorer.case
+ sim_explorer.system_interface_osp
diff --git a/names.csv b/names.csv
new file mode 100644
index 0000000..6a306d9
--- /dev/null
+++ b/names.csv
@@ -0,0 +1,27 @@
+Variable,Value
+PackageNameDashed,sim-explorer
+PackageNameCapitalized,SimExplorer
+GitHubOrganisation,dnv-opensource
+SubPackage1Name,
+Module1Name,
+SubPackage2Name,
+Module2Name,
+Author1Name,Siegfried Eisinger
+Author1Email,siegfried.eisinger@dnv.com
+Author1LinkedIn,https://www.linkedin.com/in/siegfried-eisinger-a337638b
+Author2Name,Jorge Luis Mendez
+Author2Email,jorge.luis.mendez@dnv.com
+Author2LinkedIn,https://www.linkedin.com/in/jorgelmh
+Author3Name,
+Author3Email,
+Author3LinkedIn,
+Maintainer1Name,Claas Rostock
+Maintainer1Email,claas.rostock@dnv.com
+Maintainer1LinkedIn,https://www.linkedin.com/in/claasrostock/?locale=en_US
+Maintainer2Name,
+Maintainer2Email,
+Maintainer2LinkedIn,
+Keyword1,simulation
+Keyword2,model
+Keyword3,FMI
+Keyword4,OSP
diff --git a/pyproject.toml b/pyproject.toml
index 6fcc6b2..1419fbb 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -11,7 +11,6 @@ only-include = [
".coveragerc",
".editorconfig",
".pre-commit-config.yaml",
- "manage.py",
"pyproject.toml",
"pytest.ini",
"ruff.toml",
@@ -23,15 +22,22 @@ packages = [
"src/sim_explorer",
]
+[tool.hatch.metadata]
+allow-direct-references = true
+
[project]
name = "sim-explorer"
-version = "0.2.1"
+version = "0.2.2"
description = "Experimentation tools on top of OSP simulation models."
readme = "README.rst"
-requires-python = ">= 3.10, < 3.13"
+requires-python = ">= 3.11"
license = { file = "LICENSE" }
authors = [
- { name = "Siegfried Eisinger", email = "Siegfried.Eisinger@dnv.com" },
+ { name = "Siegfried Eisinger", email = "siegfried.eisinger@dnv.com" },
+ { name = "Jorge Luis Mendez", email = "jorge.luis.mendez@dnv.com" },
+]
+maintainers = [
+ { name = "Claas Rostock", email = "claas.rostock@dnv.com" },
]
keywords = [
"simulation",
@@ -42,13 +48,13 @@ keywords = [
classifiers = [
"Development Status :: 4 - Beta",
"License :: OSI Approved :: MIT License",
- "Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
- # "Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Operating System :: Microsoft :: Windows",
"Operating System :: POSIX :: Linux",
- "Operating System :: MacOS",
+ # "Operating System :: MacOS",
"Environment :: Console",
"Intended Audience :: Developers",
"Intended Audience :: Science/Research",
@@ -56,29 +62,27 @@ classifiers = [
"Topic :: Software Development :: Libraries :: Python Modules",
]
dependencies = [
- "numpy>=1.26; python_version < '3.13'",
- "numpy>=2.2; python_version >= '3.13'",
+ "numpy>=2.3",
"matplotlib>=3.10",
"pint>=0.24",
- "sympy>=1.13",
+ "sympy>=1.14.0",
"jsonpath-ng>=1.7.0",
- "libcosimpy==0.0.2",
+ "libcosimpy>=0.0.5",
"fmpy>=0.3.21",
- "component-model>=0.1.0",
- "plotly>=5.24",
- "pydantic>=2.10.3",
+ "component-model>=0.4.0",
+ "plotly>=6.5",
+ "pydantic>=2.12",
"rich>=13.9.4",
+ "pyjson5>=1.6.8",
]
[project.optional-dependencies]
-modelTest = [
+test = [
"fmpy>=0.3.21",
+ "scipy>=1.16",
]
rest = [
- "docutils>=0.21",
-]
-editor = [
- "thonny>=4.1",
+ "docutils>=0.22.4",
]
[project.urls]
@@ -91,20 +95,21 @@ Changelog = "https://github.com/dnv-opensource/sim-explorer/blob/main/CHANGELOG.
[dependency-groups]
dev = [
- "pytest>=8.3",
- "pytest-cov>=6.0",
- "ruff>=0.9.2",
- "pyright>=1.1.392",
- "mypy>=1.14",
- "sourcery>=1.31",
- "pre-commit>=4.0",
- "Sphinx>=8.1",
- "sphinx-argparse-cli>=1.19",
- "sphinx-autodoc-typehints>=3.0",
- "sphinxcontrib-mermaid>=1.0.0",
- "myst-parser>=4.0",
- "furo>=2024.8",
- "jupyter>=1.1",
+ "pytest>=9.0",
+ "pytest-cov>=7.0",
+ "ruff>=0.15.1",
+ "pyright>=1.1.408",
+ "mypy>=1.19.1",
+ "sourcery>=1.43.0",
+ "pre-commit>=4.5",
+ "Sphinx>=9.0",
+ "sphinx-argparse-cli>=1.20.1",
+ "sphinx-autodoc-typehints>=3.6",
+ "sphinxcontrib-mermaid>=2.0",
+ "myst-parser>=5.0",
+ "furo>=2025.12",
+ "jupyter>=1.1.1",
+ "plotly-stubs>=0.1.2",
]
[tool.uv]
@@ -112,6 +117,11 @@ default-groups = [
"dev",
]
native-tls = true
+required-environments = [
+ "sys_platform == 'win32'",
+ "sys_platform == 'linux'",
+ # "sys_platform == 'darwin'",
+]
[project.scripts]
@@ -119,9 +129,7 @@ sim-explorer = "sim_explorer.cli.__main__:main"
[tool.mypy]
-plugins = [
- "numpy.typing.mypy_plugin",
-]
+plugins = []
mypy_path = "stubs"
files = [
"src",
@@ -129,7 +137,7 @@ files = [
# "demos",
]
exclude = [
- "^tests/data/",
+ "tests/data",
]
check_untyped_defs = true
disable_error_code = [
@@ -147,6 +155,10 @@ include = [
]
exclude = [
"tests/data",
+ "**/node_modules",
+ "**/__pycache__",
+ "**/.*",
+ ".venv",
]
typeCheckingMode = "basic"
@@ -172,7 +184,6 @@ reportUnnecessaryContains = "warning"
reportUnusedCallResult = "warning"
reportUnusedExpression = "warning"
reportMatchNotExhaustive = "warning"
-reportShadowedImports = "warning"
reportUntypedFunctionDecorator = "warning"
reportUntypedClassDecorator = "warning"
reportUntypedBaseClass = "error"
diff --git a/qa.bat b/qa.bat
deleted file mode 100644
index 915e0c5..0000000
--- a/qa.bat
+++ /dev/null
@@ -1,5 +0,0 @@
-uv run ruff format
-uv run ruff check
-uv run pyright
-uv run mypy
-uv run sourcery review .
diff --git a/ruff.toml b/ruff.toml
index fdea9b0..2ba651a 100644
--- a/ruff.toml
+++ b/ruff.toml
@@ -10,7 +10,7 @@ src = [
"src",
]
line-length = 120
-target-version = "py310"
+target-version = "py311"
[lint]
# Settings for Ruff linter (invoked with `uv run ruff check`).
@@ -169,12 +169,17 @@ raises-require-match-for = [
"**/utils/logging.py" = [
"A005", # Module `logging` shadows a Python standard-library module
]
-# utils/types specific ignores
-"**/utils/types.py" = [
+# docs/source/conf.py specific ignores
+"docs/source/conf.py" = [
+ "INP001", # File is part of an implicit namespace package. Add an `__init__.py`. (NOTE: conf.py is not intended to be a module, __init__.py hence not required.)
+ "A001", # Variable {name} is shadowing a Python builtin
+ "D100", # Missing docstring in public module
+]
+# types.py specific ignores
+"**/types.py" = [
"A005", # Module `types` shadows a Python standard-library module
]
-
[lint.pydocstyle]
convention = "numpy"
diff --git a/src/sim_explorer/__init__.py b/src/sim_explorer/__init__.py
index e90a269..d49a85c 100644
--- a/src/sim_explorer/__init__.py
+++ b/src/sim_explorer/__init__.py
@@ -1 +1,25 @@
"""Python Package to manage Simulation Experiments."""
+
+# NOTE: Below import of `libcosimpy.CosimLibrary` right here in the package root
+# is necessary to resolve DLL loading issues.
+#
+# When `libcosimpy.CosimLibrary` is imported, the libcosimc dll is loaded and initialized.
+# However, if `libcosimpy.CosimLibrary` gets imported by separate processes,
+# such as when pytest spawns subprocesses, or when the CLI script gets called via `uv run`
+# then it can happen the libcosimc dll gets loaded by each process.
+# Unfortunately, this leads to problems.
+#
+# Typical error messages you might encounter in this case are:
+# .../Lib/ctypes/__init__.py", line 468, in _load_library
+# OSError: [WinError 127] The specified procedure could not be found
+# or
+# The procedure entry point CRYPTO_calloc could not be located in the dynamic link library
+# /sim-explorer/venv/Lib/site-packages/libcosimpy/libcosimc/libssl-3-x64.dll.
+#
+# By importing `libcosimpy.CosimLibrary` in the `__init__.py` file of the package root,
+# we ensure that the C++ library (libcosimc dll) is loaded only once,
+# when the package gets imported.
+# It then gets (re-)used across modules, and even across subprocesses that import the package,
+# given they are spawned after this initial import.
+
+import libcosimpy.CosimLibrary
diff --git a/src/sim_explorer/assertion.py b/src/sim_explorer/assertion.py
index d5cc1c8..6819567 100644
--- a/src/sim_explorer/assertion.py
+++ b/src/sim_explorer/assertion.py
@@ -1,6 +1,7 @@
import ast
+import logging
from collections.abc import Callable, Iterable, Iterator
-from logging import warning
+from importlib import import_module
from types import CodeType
from typing import Any, TypeVar, cast, overload
@@ -8,6 +9,7 @@
from sim_explorer.case import Case, Results
from sim_explorer.models import AssertionResult, Temporal
+from sim_explorer.utils.codegen import get_callable_function
from sim_explorer.utils.types import (
TDataColumn,
TDataRow,
@@ -17,6 +19,8 @@
TValue,
)
+logger = logging.getLogger(__name__)
+
class Assertion:
"""Defines a common Assertion object for checking expectations with respect to simulation results.
@@ -242,6 +246,7 @@ def description(self, key: str, descr: str | None = None) -> str:
def assertions(
self,
key: str,
+ *,
res: bool | None = None,
details: str | None = None,
case_name: str | None = None,
@@ -268,57 +273,75 @@ def register_vars(self, variables: dict[str, dict[str, Any]]) -> None:
_ = self.symbol(key) # we allow to use the 'short name' if unique
_ = self.symbol(f"{inst}_{key}") # fully qualified name can always be used
- def make_locals(self, loc: dict[str, Any]) -> dict[str, Any]:
- """Adapt the locals with 'allowed' functions."""
- from importlib import import_module
-
+ def make_locals(self, local_ns: dict[str, Any]) -> dict[str, Any]:
+ """Amend the passed in local namespace with a controlled set of allowed symbols."""
for modulename, funclist in self._imports.items():
module = import_module(modulename)
for func in funclist:
- loc[func] = getattr(module, func)
- loc["np"] = import_module("numpy")
- return loc
+ local_ns[func] = getattr(module, func)
+ local_ns["np"] = import_module("numpy")
+ return local_ns
+
+ _T = TypeVar("_T", bound=(int | float | bool))
def _eval(
- self, func: Callable[..., int | float | bool], kvargs: dict[str, Any] | list[Any] | tuple[Any, ...]
- ) -> int | float | bool:
- """Call a function of multiple arguments and return the single result.
- All internal vecor arguments are transformed to np.arrays.
- """
- if isinstance(kvargs, dict):
- for k, v in kvargs.items():
- if isinstance(v, Iterable):
- kvargs[k] = np.array(v, float)
- return func(**kvargs)
- if isinstance(kvargs, list):
- for i, v in enumerate(kvargs):
- if isinstance(v, Iterable):
- kvargs[i] = np.array(v, dtype=float)
- return func(*kvargs)
- assert isinstance(kvargs, tuple), f"Unknown type of kvargs {kvargs}"
- _args = [] # make new, because tuple is not mutable
- for v in kvargs:
- if isinstance(v, Iterable):
- _args.append(np.array(v, dtype=float))
- else:
- _args.append(v)
- return func(*_args)
+ self,
+ func: Callable[..., _T],
+ *args: Any, # noqa: ANN401
+ **kwargs: Any, # noqa: ANN401
+ ) -> _T:
+ """Call `func` with the given positional and keyword arguments and return the result.
+
+ Iterable arguments are considered vectors and are transformed to numpy arrays before being passed to `func`.
- def eval_single(self, key: str, kvargs: dict[str, Any] | list[Any] | tuple[Any, ...]) -> int | float | bool:
+ Args:
+ func: The function to be called
+ *args: Positional arguments to be passed to `func`
+ **kwargs: Keyword arguments to be passed to `func`
+ Returns:
+ The result of calling `func` with the given arguments
+ """
+ if args:
+ _args = []
+ for v in args:
+ if isinstance(v, Iterable) and not isinstance(v, (str, bytes)):
+ _args.append(np.array(v, dtype=float))
+ else:
+ _args.append(v)
+ args = tuple(_args)
+ if kwargs:
+ for k in list(kwargs.keys()): # work on copy of keys, as we change the dict during iteration
+ v = kwargs[k]
+ if isinstance(v, Iterable) and not isinstance(v, (str, bytes)):
+ kwargs[k] = np.array(v, dtype=float)
+ return func(*args, **kwargs)
+
+ def eval_single(
+ self,
+ key: str,
+ *args: Any, # noqa: ANN401
+ **kwargs: Any, # noqa: ANN401
+ ) -> int | float | bool:
"""Perform assertion of 'key' on a single data point.
Args:
- key (str): The expression identificator to be used
- kvargs (dict|list|tuple): variable substitution kvargs as dict or args as tuple/list
- All required variables for the evaluation shall be listed.
- Results:
+ key (str): The identifier of the expression to be evaluated
+ *args: Positional arguments used in the expression, as a list or tuple.
+ **kwargs: Keyword arguments used in the expression, as a dict.
+
+ Returns
+ -------
(bool) result of assertion
"""
assert key in self._compiled, f"Expression {key} not found"
- loc = self.make_locals(locals())
- exec(self._compiled[key], loc, loc) # noqa: S102
- # print("kvargs", kvargs, self._syms[key], self.expr_get_symbols_functions(key)) # noqa: ERA001
- return self._eval(locals()[f"_{key}"], kvargs)
+ local_ns = self.make_locals({})
+ func = get_callable_function(
+ compiled=self._compiled[key],
+ function_name=f"_{key}",
+ global_ns=local_ns,
+ local_ns=local_ns,
+ )
+ return self._eval(func, *args, **kwargs)
_VT = TypeVar("_VT", bound=TDataColumn | TValue)
@@ -366,7 +389,7 @@ def eval_series( # noqa: C901, PLR0912, PLR0915
`bool` : (time, True/False) for first row evaluating to True.
`bool-list` : (times, True/False) for all data points in the series
`A` : Always true for the whole time-series. Same as 'bool'
- `F` : is True at end of time series.
+ `F` : Eventually True at some point in the time series.
Callable : run the given callable on times, expr(data)
None : Use the internal 'temporal(key)' setting
Results:
@@ -379,10 +402,13 @@ def eval_series( # noqa: C901, PLR0912, PLR0915
argument_names = self._syms[key]
# Execute the compiled expression. This will create a function with name _ in the local namespace.
- _locals = self.make_locals(locals())
- exec(self._compiled[key], _locals, _locals) # noqa: S102
- # Save a reference to the created function in a local variable, for easier access.
- func = locals()[f"_{key}"]
+ _locals = self.make_locals({})
+ func = get_callable_function(
+ compiled=self._compiled[key],
+ function_name=f"_{key}",
+ global_ns=_locals,
+ local_ns=_locals,
+ )
_temp = self._temporal[key]["type"] if ret is None else Temporal.UNDEFINED
@@ -422,9 +448,9 @@ def eval_series( # noqa: C901, PLR0912, PLR0915
if _times:
assert all(isinstance(t, TNumeric) for t in _times), f"Time data in eval_series is not numeric: {_times}"
if not all(isinstance(t, type(_times[0])) for t in _times):
- warning("Time data in eval_series has varying type. All time values will be converted to float.")
+ logger.warning("Time data in eval_series has varying type. All time values will be converted to float.")
_times = [float(t) for t in _times]
- times = cast(TTimeColumn, list(_times))
+ times = cast("TTimeColumn", list(_times))
# Results: Assert that all values in temporary list `_results` are of a valid type and of the same type,
# then cast the temporary list `_results` into list `results` of invariant type `TDataColumn`.
@@ -433,9 +459,11 @@ def eval_series( # noqa: C901, PLR0912, PLR0915
f"Result data in eval_series is of an invalid type: {_results}"
)
if not all(isinstance(r, type(_results[0])) for r in _results):
- warning("Result data in eval_series has varying type. All result values will be converted to bool.")
+ logger.warning(
+ "Result data in eval_series has varying type. All result values will be converted to bool."
+ )
_results = [bool(r) for r in _results]
- results = cast(TDataColumn, list(_results))
+ results = cast("TDataColumn", list(_results))
# Apply an evaluation metric on the result values, specified through parameter `ret`.
# Depending on the value of `ret`, either temporal logic, interpolation, or a user-defined callable function is applied.
@@ -444,7 +472,7 @@ def eval_series( # noqa: C901, PLR0912, PLR0915
_res = all(results)
evaluation = (times[0] if _res else times[results.index(False)], _res)
- elif (ret is None and _temp == Temporal.F) or (isinstance(ret, str) and ret == "F"): # Finally True?
+ elif (ret is None and _temp == Temporal.F) or (isinstance(ret, str) and ret == "F"): # Eventually True?
r_prev = results[-1]
t_prev = times[-1]
for i in range(min(len(times), len(results)) - 1, -1, -1):
@@ -486,7 +514,6 @@ def do_assert(
"""Perform assert action 'key' on data of 'result' object."""
assert isinstance(key, str), f"Key should be a string. Found {key}"
assert key in self._temporal, f"Assertion key {key} not found"
- from sim_explorer.case import Results
assert isinstance(result, Results), f"Results object expected. Found {result}"
inst: list[str] = []
@@ -498,7 +525,7 @@ def do_assert(
assert isinstance(_var, str), f"Variable should be a string. Found {_var}"
inst.append(_inst)
var.append(_var)
- assert len(var), "No variables to retrieve"
+ assert var, "No variables to retrieve"
if var[0] == "t": # the independent variable is always the first column in data
_ = inst.pop(0)
_ = var.pop(0)
@@ -530,14 +557,20 @@ def report(self, case: Case | None = None) -> Iterator[AssertionResult]:
"""
def do_report(key: str) -> AssertionResult:
- time_arg = self._temporal[key].get("args", None)
+ time_arg: list[Any] | None = self._temporal[key].get("args", None)
+ time: int | float | None = (
+ time_arg[0] if time_arg and len(time_arg) > 0 and isinstance(time_arg[0], (int, float)) else None
+ )
+ temporal: Temporal | None = self._temporal[key].get("type", None)
+ if temporal is None:
+ raise ValueError(f"Temporal for assertion {key} is not defined.")
return AssertionResult(
key=key,
expression=self._expr[key],
- time=(time_arg[0] if len(time_arg) > 0 and (isinstance(time_arg[0], int | float)) else None),
+ time=time,
result=self._assertions[key].get("passed", False),
description=self._description[key],
- temporal=self._temporal[key].get("type", None),
+ temporal=temporal,
case=self._assertions[key].get("case", None),
details="No details",
)
diff --git a/src/sim_explorer/case.py b/src/sim_explorer/case.py
index 8525508..c88ed6d 100644
--- a/src/sim_explorer/case.py
+++ b/src/sim_explorer/case.py
@@ -1,8 +1,20 @@
-r"""
-Python module to manage cases
-with respect to reading \*.cases files, running cases and storing results.
-"""
+r"""sim_explorer module for definition and execution of simulation experiments.
+
+This module serves the definition and execution of simulation experiments, defined as 'cases'.
+With respect to DoE or "smart testing", this module serves the preparation of start conditions.
+Main functionalities are:
+* Read and compile the case definitions from a \*.cases configuration file
+Note that Json5 is restriced to 'ordered keys' and 'unique keys within an object'
+* Set the start variables for a given case
+* Run cases
+* Manipulate variables according to conditions during the simulation run
+* Save requested variables at given communication points during a simulation run
+* Collect and store results
+* Check the validity of results when saving variables
+
+Note: The classes Case and Cases should be kept together in this file to avoid circular references.
+"""
# pyright: reportUnnecessaryTypeIgnoreComment=false
from __future__ import annotations
@@ -10,7 +22,7 @@
import copy
import logging
from collections.abc import Callable, Generator, Iterable, Iterator, Sequence
-from datetime import datetime, timezone
+from datetime import UTC, datetime
from pathlib import Path
from typing import TYPE_CHECKING, Any, TypeVar, cast, overload
@@ -18,10 +30,10 @@
import numpy as np
from sim_explorer.exceptions import CaseInitError
-from sim_explorer.json5 import Json5
from sim_explorer.models import Temporal
from sim_explorer.system_interface import SystemInterface
from sim_explorer.system_interface_osp import SystemInterfaceOSP
+from sim_explorer.utils.json5 import json5_check, json5_path, json5_read, json5_update, json5_write
from sim_explorer.utils.misc import from_xml
from sim_explorer.utils.paths import get_path, relative_path
from sim_explorer.utils.types import (
@@ -32,6 +44,8 @@
)
if TYPE_CHECKING:
+ import os
+
from sim_explorer.utils.types import (
TDataTable,
TTimeColumn,
@@ -40,20 +54,6 @@
logger = logging.getLogger(__name__)
-"""
-sim_explorer module for definition and execution of simulation experiments
-* read and compile the case definitions from configuration file
- Note that Json5 is here restriced to 'ordered keys' and 'unique keys within an object'
-* set the start variables for a given case
-* manipulate variables according to conditions during the simulation run
-* save requested variables at given communication points during a simulation run
-* check the validity of results when saving variables
-
-With respect to MVx in general, this module serves the preparation of start conditions for smart testing.
-Note: The classes Case and Cases should be kept together in this file to avoid circular references.
-"""
-
-
class Case:
"""Instantiation of a Case object.
Sub-cases are strored ins list 'self.subs'.
@@ -75,15 +75,17 @@ def __init__( # noqa: C901
) -> None:
self.cases: Cases = cases
self.name: str = name
- self.js: Json5 = Json5(spec)
- self.description: str = self.js.jspath("$.description", str) or ""
+ # `spec` is the case specification as a dictionary. It must be valid Json5 code.
+ assert json5_check(spec), f"The specification {spec} of case {name} is not valid Json5 code."
+ self.js_py: dict[str, Any] = spec
+ self.description: str = json5_path(js5=self.js_py, path="$.description", typ=str) or ""
self.subs: list[Case] = [] # own subcases
- self.res: Results | None = None
+ self.results: Results | None = None
if name == "base":
self.parent = None
else: # all other cases need a parent
- parent_name = self.js.jspath("$.parent", str) or "base"
+ parent_name = json5_path(js5=self.js_py, path="$.parent", typ=str) or "base"
parent_case = self.cases.case_by_name(parent_name)
assert isinstance(parent_case, Case), f"Parent case for {self.name} required. Found {parent_name}"
self.parent = parent_case
@@ -109,27 +111,27 @@ def __init__( # noqa: C901
self.act_set = copy.deepcopy(self.parent.act_set)
if self.cases.simulator.full_simulator_available:
- _spec: dict[str, Any] | None = self.js.jspath(path="$.spec", typ=dict, error_msg=True)
- assert _spec is not None, f"Specification for case {self.name} not found"
+ _spec: dict[str, Any] | None = json5_path(js5=self.js_py, path="$.spec", typ=dict)
+ assert isinstance(_spec, dict), f"Specification for case {self.name} not found"
for k, v in _spec.items():
self.read_spec_item(key=k, value=v)
- _results: list[Any] | None = self.js.jspath(path="$.results", typ=list)
- if _results is not None:
+ _results: list[Any] | None = json5_path(js5=self.js_py, path="$.results", typ=list)
+ if isinstance(_results, list):
for _res in _results:
self.read_spec_item(key=_res)
self.asserts: list[str] = [] # list of assert keys
- _assert: dict[str, Any] | None = self.js.jspath(path="$.assert", typ=dict)
- if _assert is not None:
+ _assert: dict[str, Any] | None = json5_path(js5=self.js_py, path="$.assert", typ=dict)
+ if isinstance(_assert, dict):
for k, v in _assert.items():
_ = self.read_assertion(key=k, expr_descr=v)
if self.name == "base":
self.special = self._ensure_specials(self.special) # must specify for base case
self.act_get = dict(sorted(self.act_get.items()))
self.act_set = dict(sorted(self.act_set.items()))
- # self.res represents the Results object and is added when collecting results or when evaluating results
+ # self.results represents the Results object and is added when collecting results or when evaluating results
def add_results_object(self, res: Results) -> None:
- self.res = res
+ self.results = res
def iter(self) -> Generator[Case, None, None]:
"""Construct an iterator, allowing iteration from base case to this case through the hierarchy."""
@@ -140,7 +142,7 @@ def iter(self) -> Generator[Case, None, None]:
if nxt.parent is None:
break
nxt = nxt.parent
- while len(h):
+ while h:
yield h.pop()
def case_by_name(self, name: str) -> Case | None:
@@ -202,7 +204,7 @@ def time_spec(at: str) -> tuple[Temporal, tuple[str | float, ...]]:
for i in range(len(at) - 1, -1, -1):
try:
typ = Temporal[at[i]]
- except KeyError: # noqa: PERF203
+ except KeyError:
pass
else:
if at[i + 1 :].strip() == "":
@@ -424,7 +426,7 @@ def get_from_config(element: str, default: float | None = None) -> float | None:
raise CaseInitError("'stepSize' should be specified as part of the 'base' specification.") from None
return special
- def run(self, dump: str | None = "") -> None: # noqa: C901, PLR0912, PLR0915
+ def run(self, dump: str | os.PathLike[str] | None = None) -> None: # noqa: C901, PLR0912, PLR0915
"""Set up case and run it.
All get action are recorded in results and get actions always concern whole case variables.
@@ -432,7 +434,7 @@ def run(self, dump: str | None = "") -> None: # noqa: C901, PLR0912, PLR0915
changed with initial settings (settings before the main simulation loop) and reported.
Args:
- dump (str): Optionally save the results as json file.
+ dump (str | os.PathLike[str] | None): Optionally save the results as json file.
None: do not save, '': use default file name, str (with or without '.js5'): save with that file name
"""
_VT = TypeVar("_VT", TGetActionArgs, TSetActionArgs)
@@ -468,8 +470,8 @@ def do_actions(
typ=self.cases.variables[_act[0]]["type"],
)
if len(_act) == 3: # get action. Report # noqa: PLR2004
- assert self.res is not None
- self.res.add(
+ assert self.results is not None
+ self.results.add(
time=time / self.cases.timefac,
comp=_act[1],
cvar=_act[0],
@@ -481,7 +483,7 @@ def do_actions(
_t, actions = 10 * tstop, []
return (_t, actions)
- _ = self.cases.simulator.init_simulator()
+ assert self.cases.simulator.init_simulator(), "Simulator initialization not successfull"
# Note: final actions are included as _get at stopTime
assert self.special is not None
tstart: int = int(self.special["startTime"] * self.cases.timefac)
@@ -536,16 +538,15 @@ def do_actions(
values=_values,
)
starts[cvar] = values
-
- for v, s in starts.items(): # report the start values
- for c in self.cases.variables[cvar]["instances"]:
- assert self.res is not None
- self.res.add(
- time=tstart,
- comp=c,
- cvar=v,
- values=s,
- )
+ for v, s in starts.items(): # report the start values
+ for c in self.cases.variables[cvar]["instances"]:
+ assert self.results is not None
+ self.results.add(
+ time=tstart,
+ comp=c,
+ cvar=v,
+ values=s,
+ )
while True: # main simulation loop
t_set, a_set = do_actions(
@@ -567,19 +568,18 @@ def do_actions(
time=time,
)
- if len(act_step): # there are step-always actions
+ if act_step: # there are step-always actions
for cvar, comp, _refs, a in act_step:
- assert self.res is not None
- self.res.add(
+ assert self.results is not None
+ self.results.add(
time=time / self.cases.timefac,
comp=comp,
cvar=cvar,
values=a(),
)
- if dump is not None:
- assert self.res is not None
- self.res.save(dump)
+ if self.results is not None:
+ self.results.save(dump)
class Cases:
@@ -591,7 +591,7 @@ class Cases:
* Definition of cases and their relation (case hierarchy)
Args:
- spec (Path): file name for cases specification
+ spec (str | os.PathLike[str]): file name for cases specification
simulator_type (SystemInterface)=SystemInterfaceOSP: Optional possibility to choose system simulator details
Default is OSP (libcosimpy), but when only results are read the basic SystemInterface is sufficient.
"""
@@ -600,23 +600,31 @@ class Cases:
"assertion",
"base",
"file",
- "js",
- "results_print_type",
+ "js_py",
"simulator",
- "spec",
"timefac",
"variables",
)
- def __init__(self, spec: str | Path) -> None:
- self.file: Path = Path(spec) # everything relative to the folder of this file!
+ def __init__(self, spec: str | os.PathLike[str]) -> None:
+ spec = spec if isinstance(spec, Path) else Path(spec)
+ self.file: Path = spec
assert self.file.exists(), f"Cases spec file {spec} not found"
- self.js: Json5 = Json5(spec)
- name: str = self.js.jspath("$.header.name", str) or ""
- description: str = self.js.jspath("$.header.description", str) or ""
- log_level: str = self.js.jspath("$.header.logLevel") or "fatal"
- modelfile: str = self.js.jspath("$.header.modelFile", str) or "OspSystemStructure.xml"
- simulator: str = self.js.jspath("$.header.simulator", str) or ""
+ self.js_py = json5_read(spec)
+ header = json5_path(js5=self.js_py, path="$.header", typ=dict)
+ assert isinstance(header, dict), f"No header found in {self.js_py}"
+ name: str = json5_path(js5=header, path="$.name", typ=str) or ""
+ description: str = json5_path(js5=header, path="$.description", typ=str) or ""
+ log_level: str = json5_path(js5=header, path="$.logLevel", typ=str) or "fatal"
+ modelfile: str = json5_path(js5=header, path="$.modelFile", typ=str) or "OspSystemStructure.xml"
+ simulator: str = json5_path(js5=header, path="$.simulator", typ=str) or "" # Note: default only results reading
+ # TODO @ClaasRostock: The model file is currently expected to be in the same folder as the cases file.
+ # This is a limitation. It should be possible for a user to specify a path to e.g. an OspSystemStructure.xml
+ # which does not reside in the same folder as the cases file.
+ # A more flexible solution would be to allow to specify the path to the model file in the header,
+ # but this would require some changes in the code and in the specification format.
+ # For now, we keep it simple and expect the model file to be in the same folder as the cases file.
+ # CLAROS, 2026-03-16
path: Path = self.file.parent / modelfile
assert path.exists(), f"System structure file {path} not found"
if not simulator: # without ability to perform simulations
@@ -627,7 +635,8 @@ def __init__(self, spec: str | Path) -> None:
self.timefac: float = self._get_time_unit() * 1e9 # internally OSP uses pico-seconds as integer!
# read the 'variables' section and generate dict { alias : { (instances), (variables)}}:
self.variables: dict[str, dict[str, Any]] = self.get_case_variables()
- from sim_explorer.assertion import Assertion
+
+ from sim_explorer.assertion import Assertion # noqa: PLC0415 # to avoid circular import
self.assertion: Assertion = Assertion()
self.assertion.register_vars(self.variables) # register variables as symbols
@@ -651,9 +660,7 @@ def get_case_variables(self) -> dict[str, dict[str, Any]]:
"""
variables: dict[str, dict[str, Any]] = {}
model_vars: dict[str, dict[str, dict[str, Any]]] = {} # cache of variables of models
- variables_in_spec: dict[str, list[str] | Any] = (
- self.js.jspath(path="$.header.variables", typ=dict, error_msg=True) or {}
- )
+ variables_in_spec: dict[str, list[str] | Any] = json5_path(self.js_py, "$.header.variables", dict) or {}
for k, v in variables_in_spec.items():
if not isinstance(v, list):
raise CaseInitError(f"List of 'component(s)' and 'variable(s)' expected. Found {v}") from None
@@ -725,7 +732,7 @@ def _get_time_unit(self) -> float: # noqa: PLR0911
If the entry is not found, 1 second is assumed.
"""
# _unit =
- unit = self.js.jspath("$.header.timeUnit", str) or "second"
+ unit = json5_path(self.js_py, "$.header.timeUnit", str) or "second"
if unit.lower().startswith("sec"):
return 1.0
if unit.lower().startswith("min"):
@@ -750,19 +757,22 @@ def read_cases(self) -> None:
The 'header' is treated elsewhere.
"""
- if self.js.jspath(path="$.base", typ=dict) is None or self.js.jspath(path="$.base.spec", typ=dict) is None:
- raise CaseInitError(f"Main section 'base' is needed. Found {list(self.js.js_py.keys())}") from None
+ if (
+ json5_path(js5=self.js_py, path="$.base", typ=dict) is None
+ or json5_path(js5=self.js_py, path="$.base.spec", typ=dict) is None
+ ):
+ raise CaseInitError(f"Main section 'base' is needed. Found {list(self.js_py.keys())}")
# we need to peek into the base case where startTime and stopTime should be defined
- start_time: float = self.js.jspath(path="$.base.spec.startTime", typ=float) or 0.0
- stop_time: float | None = self.js.jspath(path="$.base.spec.stopTime", typ=float, error_msg=True)
+ start_time: float = json5_path(self.js_py, "$.base.spec.startTime", float) or 0.0
+ stop_time: float | None = json5_path(self.js_py, "$.base.spec.stopTime", float)
assert stop_time is not None, "Stop time not defined in the base case"
special: dict[str, float] = {
"startTime": start_time,
"stopTime": stop_time,
}
# all case definitions are top-level objects in self.spec. 'base' is mandatory
- spec: dict[str, Any] | None = self.js.jspath(path="$.base", typ=dict, error_msg=True)
+ spec: dict[str, Any] | None = json5_path(self.js_py, "$.base", dict)
assert spec is not None, "Base case not found in the Cases spec"
self.base = Case(
cases=self,
@@ -770,9 +780,9 @@ def read_cases(self) -> None:
spec=spec,
special=special,
)
- for k in self.js.js_py:
+ for k in self.js_py:
if k not in ("header", "base"):
- case_spec: dict[str, Any] | None = self.js.jspath(path=f"$.{k}", typ=dict, error_msg=True)
+ case_spec: dict[str, Any] | None = json5_path(self.js_py, f"$.{k}", dict)
assert case_spec is not None, f"Case {k} not found in the Cases spec."
_ = Case(
cases=self,
@@ -795,10 +805,9 @@ def case_by_name(self, name: str) -> Case | None:
found = self.base.case_by_name(name)
return found
- def disect_variable( # noqa: C901
+ def disect_variable(
self,
key: str,
- err_level: int = 2,
) -> tuple[str, dict[str, Any] | None, list[int]]:
"""Extract the variable name, definition and explicit variable range, if relevant
(multi-valued variables, where only some elements are addressed).
@@ -813,33 +822,16 @@ def disect_variable( # noqa: C901
2. The variable definition, which the name refers to
3. A tuple with indices of the variable, i.e. the range
"""
-
- def handle_error(
- msg: str,
- err: Exception | None,
- level: int,
- ) -> tuple[str, dict[str, Any] | None, list[int]]:
- if level > 0:
- if level == 1:
- logger.warning(msg)
- else:
- raise AssertionError(msg) from err
- return ("", None, [])
-
pre, _, r = key.partition("[")
try:
cvar_info = self.variables[pre]
except KeyError as e:
- _ = handle_error(
- msg=f"Variable {pre} was not found in list of defined case variables",
- err=e,
- level=err_level,
- )
+ raise KeyError(f"Variable {pre} was not found in list of defined case variables") from e
cvar_len = len(cvar_info["names"]) # len of the tuple of refs
rng: list[int] = []
if len(r): # range among several variables
- r = r.rstrip("]").strip() # string version of a non-trivial range
+ r = r.rstrip("]").strip().strip("]") # string version of a non-trivial range
parts_comma = r.split(",")
for i, p in enumerate(parts_comma):
parts_ellipses = p.split("..")
@@ -847,17 +839,9 @@ def handle_error(
try:
idx = int(p)
except ValueError as e:
- return handle_error(
- msg=f"Unhandled index {p}[{i}] for variable {pre}",
- err=e,
- level=err_level,
- )
+ raise ValueError(f"Unhandled index {p}[{i}] for variable {pre}") from e
if not 0 <= idx < cvar_len:
- return handle_error(
- msg=f"Index {idx} of variable {pre} out of range",
- err=None,
- level=err_level,
- )
+ raise ValueError(f"Index {idx} of variable {pre} out of range") from None
rng.append(idx)
else:
assert len(parts_ellipses) == 2, f"RangeError: Exactly two indices expected in {p} of {pre}" # noqa: PLR2004
@@ -868,11 +852,7 @@ def handle_error(
idx1 = cvar_len if len(parts_ellipses[1]) == 0 else int(parts_ellipses[1])
assert idx0 <= idx1 <= cvar_len, f"Index {idx1} of variable {pre} out of range"
except ValueError as e:
- return handle_error(
- msg="Unhandled ellipses '{parts_comma}' for variable {pre}",
- err=e,
- level=err_level,
- )
+ raise ValueError("Unhandled ellipses '{parts_comma}' for variable {pre}") from e
rng = list(range(idx0, idx1))
elif cvar_len == 1: # scalar variable
rng = [0]
@@ -892,10 +872,12 @@ def info(self, case: Case | None = None, level: int = 0) -> str:
txt: str = ""
if case is None:
case = self.base
+ header = json5_path(js5=self.js_py, path="$.header", typ=dict)
+ assert isinstance(header, dict), f"Header element not found in specification {self.js_py}"
txt += "Cases "
- txt += f"{self.js.jspath('$.header.name', str) or 'noName'}. "
- txt += f"{(self.js.jspath('$.header.description', str) or '')}\n"
- modelfile = self.js.jspath("$.header.modelFile", str)
+ txt += f"{json5_path(js5=header, path='$.name', typ=str) or 'noName'}. "
+ txt += f"{json5_path(js5=header, path='$.description', typ=str) or ''}\n"
+ modelfile = json5_path(js5=header, path="$.modelFile", typ=str)
if modelfile is not None:
txt += f"System spec '{modelfile}'.\n"
assert isinstance(case, Case), "At this point a Case object is expected as variable 'case'"
@@ -909,7 +891,7 @@ def info(self, case: Case | None = None, level: int = 0) -> str:
def run_case(
self,
name: str | Case,
- dump: str | None = "",
+ dump: str | os.PathLike[str] | None = None,
*,
run_subs: bool = False,
run_assertions: bool = False,
@@ -927,8 +909,8 @@ def run_case(
if run_assertions and c:
# Run assertions on every case after running the case -> results will be saved in memory for now
- assert c.res is not None
- _ = self.assertion.do_assert_case(c.res)
+ assert c.results is not None
+ _ = self.assertion.do_assert_case(c.results)
if not run_subs:
return
@@ -950,11 +932,11 @@ class Results:
* Read results from file and work with them
Args:
- case (Case,str,Path)=None: The case object, the results relate to.
+ case (Case | None)=None: The case object, the results relate to.
When instantiating from Case (for collecting data) this shall be explicitly provided.
When instantiating from stored results, this should refer to the cases definition,
or the default file name .cases is expected.
- file (Path,str)=None: The file where results are saved (as Json5).
+ file (str | os.PathLike[str] | None)=None: The file where results are saved (as Json5).
When instantiating from stored results (for working with data) this shall be explicitly provided.
When instantiating from Case, this file name will be used for storing results.
If "" default file name is used, if None, results are not stored.
@@ -962,32 +944,35 @@ class Results:
def __init__(
self,
- case: Case | str | Path | None = None,
- file: str | Path | None = None,
+ case: Case | None = None,
+ file: str | os.PathLike[str] | None = None,
) -> None:
self.file: Path | None # None denotes that results are not automatically saved
self.case: Case | None = None
- self.res: Json5
- if (case is None or isinstance(case, str | Path)) and file is not None:
+ self.res: dict[str, Any] = {}
+ if case is None and file is not None:
+ file = file if isinstance(file, Path) else Path(file)
self._init_from_existing(file) # instantiating from existing results file (work with data)
- elif isinstance(case, Case): # instantiating from cases file (for data collection)
+ elif isinstance(case, Case): # instantiating from case file (for data collection)
self._init_new(case)
else:
raise ValueError(f"Inconsistent init arguments case:{case}, file:{file}")
- def _init_from_existing(self, file: str | Path) -> None:
- self.file = Path(file)
+ def _init_from_existing(self, file: Path) -> None:
+ self.file = file
assert self.file.exists(), f"File {file} is expected to exist."
- self.res = Json5(self.file)
- cases_name: str | None = self.res.jspath(path="$.header.cases", typ=str, error_msg=True)
- assert cases_name is not None, "Cases name not found in results file."
- case = Path(self.file.parent / f"{cases_name}.cases")
+ self.res = json5_read(self.file)
+ header: dict[str, Any] | None = json5_path(js5=self.res, path="$.header", typ=dict)
+ assert header is not None, f"No header found in results file {file}"
+ cases_name: str | None = json5_path(js5=header, path="$.cases", typ=str)
+ assert cases_name is not None, f"No cases entry found in header of results file {file}"
+ _cases = Path(self.file.parent / f"{cases_name}.cases")
try:
- cases = Cases(spec=Path(case))
- except ValueError:
- raise CaseInitError(f"Cases {Path(case)} instantiation error") from ValueError
- case_name: str | None = self.res.jspath(path="$.header.case", typ=str, error_msg=True)
- assert case_name is not None, "Case name not found in results file."
+ cases = Cases(spec=Path(_cases))
+ except ValueError as e:
+ raise CaseInitError(f"Cases {Path(_cases)} instantiation error") from e
+ case_name: str | None = json5_path(js5=header, path="$.case", typ=str)
+ assert case_name is not None, f"Case name not found in results file {file}"
self.case = cases.case_by_name(case_name)
assert self.case is not None, f"Case {case_name} not found."
assert isinstance(self.case.cases, Cases), "Cases object not defined."
@@ -997,18 +982,12 @@ def _init_from_existing(self, file: str | Path) -> None:
def _init_new(
self,
case: Case,
- file: str | Path | None = "",
+ file: Path | None = None,
) -> None:
assert isinstance(case, Case), f"Case object expected as 'case' in Results. Found {type(case)}"
self.case = case
- if file is not None: # use that for storing results data as Json5
- if file == "": # use default file name (can be changed through self.save():
- self.file = self.case.cases.file.parent / f"{self.case.name}.js5"
- else:
- self.file = Path(file)
- else: # do not store data
- self.file = None
- self.res = Json5(str(self._header_make())) # instantiate the results object
+ self.file = file or Path(f"{self.case.name}.js5") # use case name as default file name, if not provided
+ self.res = self._header_make() # instantiate the results dict
self._header_transform(to_string=False)
def _header_make(self) -> dict[str, dict[str, Any]]:
@@ -1017,17 +996,16 @@ def _header_make(self) -> dict[str, dict[str, Any]]:
"""
assert self.case is not None, "Case object not defined"
assert self.file is not None, "File name not defined"
- _ = self.case.cases.js.jspath(path="$.header.name", typ=str, error_msg=True)
+ header: dict[str, Any] | None = json5_path(js5=self.case.cases.js_py, path="$.header", typ=dict)
+ assert isinstance(header, dict), "Header not found in cases spec"
results: dict[str, dict[str, Any]] = {
"header": {
"case": self.case.name,
- "dateTime": datetime.now(tz=timezone.utc).isoformat(),
- "cases": self.case.cases.js.jspath(path="$.header.name", typ=str, error_msg=True),
- "file": relative_path(p1=Path(self.case.cases.file), p2=self.file),
- "casesDate": datetime.fromtimestamp(
- timestamp=self.case.cases.file.stat().st_mtime, tz=timezone.utc
- ).isoformat(),
- "timeUnit": self.case.cases.js.jspath(path="$.header.timeUnit", typ=str) or "sec",
+ "dateTime": datetime.now(tz=UTC).isoformat(),
+ "cases": json5_path(js5=header, path="$.name", typ=str) or "noName",
+ "file": relative_path(p1=self.case.cases.file, p2=self.file),
+ "casesDate": datetime.fromtimestamp(timestamp=self.case.cases.file.stat().st_mtime, tz=UTC).isoformat(),
+ "timeUnit": json5_path(js5=header, path="$.timeUnit", typ=str) or "sec",
"timeFactor": self.case.cases.timefac,
}
}
@@ -1041,46 +1019,54 @@ def _header_transform(
"""Transform the header back- and forth between python types and string.
to_string=True is used when saving to file and =False is used when reading from file.
"""
- assert isinstance(self.file, Path), f"Need a proper file at this point. Found {self.file}"
+ assert self.file is not None, (
+ f"Attribute `file` of this `Results` instance must be set at this point. Found {self.file}"
+ )
res = self.res
_date_time: datetime | str | None
_cases_date: datetime | str | None
_file: Path | str | None
if to_string:
- _date_time = res.jspath(path="$.header.dateTime", typ=datetime, error_msg=True)
+ _date_time = json5_path(js5=res, path="$.header.dateTime", typ=datetime)
assert _date_time is not None, "DateTime not found in results header"
- res.update(
+ json5_update(
+ js5=res,
spath="$.header.dateTime",
data=_date_time.isoformat(),
)
- _cases_date = res.jspath(path="$.header.casesDate", typ=datetime, error_msg=True)
+ _cases_date = json5_path(js5=res, path="$.header.casesDate", typ=datetime)
assert _cases_date is not None, "CasesDate not found in results header"
- res.update(
+ json5_update(
+ js5=res,
spath="$.header.casesDate",
data=_cases_date.isoformat(),
)
- _file = res.jspath(path="$.header.file", typ=Path, error_msg=True)
+ _file = json5_path(js5=res, path="$.header.file", typ=Path)
assert _file is not None, "File not found in results header"
- res.update(
+ json5_update(
+ js5=res,
spath="$.header.file",
data=relative_path(p1=_file, p2=self.file),
)
else:
- _date_time = res.jspath(path="$.header.dateTime", typ=str, error_msg=True)
+ _date_time = json5_path(js5=res, path="$.header.dateTime", typ=str)
assert _date_time is not None, "DateTime not found in results header"
- res.update(
+ json5_update(
+ js5=res,
spath="$.header.dateTime",
data=datetime.fromisoformat(_date_time),
)
- _cases_date = res.jspath(path="$.header.casesDate", typ=str, error_msg=True)
+ _cases_date = json5_path(js5=res, path="$.header.casesDate", typ=str)
assert _cases_date is not None, "CasesDate not found in results header"
- res.update(
+ json5_update(
+ js5=res,
spath="$.header.casesDate",
data=datetime.fromisoformat(_cases_date),
)
- _file = res.jspath(path="$.header.file", typ=str, error_msg=True)
+ _file = json5_path(js5=res, path="$.header.file", typ=str)
assert _file is not None, "File not found in results header"
- res.update(
+ json5_update(
+ js5=res,
spath="$.header.file",
data=get_path(p1=_file, base=self.file.parent),
)
@@ -1102,28 +1088,26 @@ def add(
"""
# print(f"Update ({time}): {comp}: {cvar} : {values}") # noqa: ERA001
_values = values[0] if isinstance(values, Sequence) and len(values) == 1 else values
- self.res.update(
- spath=f"$[{time}]{comp}",
- data={cvar: _values},
- )
+ json5_update(self.res, keys=(str(time), comp), data={cvar: _values})
- def save(self, jsfile: str | Path = "") -> None:
- """Dump the results dict to a json5 file.
+ def save(self, jsfile: str | os.PathLike[str] | None = None) -> None:
+ """Dump the results dict to a Json5 file.
Args:
- jsfile (str|Path): Optional possibility to change the default name (self.case.name.js5) to use for dump.
+ jsfile (str | os.PathLike[str] | None): Optional. File to dump to. If not provided, `self.file` will be used.
"""
if self.file is None:
return
- if jsfile == "":
+ if not jsfile:
jsfile = self.file
else: # a new file name is provided
if isinstance(jsfile, str) and not jsfile.endswith(".js5"):
jsfile += ".js5"
- jsfile = Path(self.case.cases.file.parent / jsfile) # type: ignore [union-attr]
+ if not isinstance(jsfile, Path):
+ jsfile = Path(jsfile)
self.file = jsfile # remember the new file name
self._header_transform(to_string=True)
- _ = self.res.write(jsfile)
+ json5_write(self.res, jsfile)
def inspect(
self,
@@ -1139,30 +1123,31 @@ def inspect(
Returns
-------
A dictionary { : {'len':#data points, 'range':[tMin, tMax], 'info':info-dict}
- The info-dict is and element of Cases.variables. See Cases.get_case_variables() for definition.
+ The info-dict is an element of Cases.variables. See Cases.get_case_variables() for definition.
"""
cont: dict[str, dict[str, Any]] = {}
assert isinstance(self.case, Case)
assert isinstance(self.case.cases, Cases)
- for _time, components in self.res.js_py.items():
+ for _time, components in self.res.items():
if _time != "header":
time = float(_time)
for c, variables in components.items():
- if component is None or c == component:
- for v in variables:
- if variable is None or variable == v:
- ident: str = f"{c}.{v}"
- if ident in cont: # already registered
- cont[ident]["range"][1] = time # update upper bound
- cont[ident]["len"] += 1 # update length
- else: # new entry
- v_name, v_info, v_range = self.case.cases.disect_variable(v, err_level=0)
- assert len(v_name), f"Variable {v} not found in cases spec {self.case.cases.file}"
- cont[ident] = {
- "len": 1,
- "range": [time, time],
- "info": v_info,
- }
+ if component is not None and c != component:
+ continue
+ for v in variables:
+ if variable is None or variable == v:
+ ident: str = f"{c}.{v}"
+ if ident in cont: # already registered
+ cont[ident]["range"][1] = time # update upper bound
+ cont[ident]["len"] += 1 # update length
+ else: # new entry
+ v_name, v_info, _v_range = self.case.cases.disect_variable(v)
+ assert len(v_name), f"Variable {v} not found in cases spec {self.case.cases.file}"
+ cont[ident] = {
+ "len": 1,
+ "range": [time, time],
+ "info": v_info,
+ }
return cont
def retrieve(self, comp_var: Iterable[str | tuple[str, str]]) -> TDataTable:
@@ -1170,7 +1155,7 @@ def retrieve(self, comp_var: Iterable[str | tuple[str, str]]) -> TDataTable:
Args:
comp_var (Iterable): Iterable of (, [, element])
- Alternatively, the jspath syntax .[[element]] can be used as comp_var.
+ Alternatively, the json_path syntax .[[element]] can be used as comp_var.
Time is not explicitly included in comp_var
A record is only included if all variables are found for a given time
Returns:
@@ -1191,7 +1176,7 @@ def retrieve(self, comp_var: Iterable[str | tuple[str, str]]) -> TDataTable:
comp, var = _cv
_comp_var.append((comp, var, el))
- for key, values in self.res.js_py.items():
+ for key, values in self.res.items():
if key == "header":
continue
time: float = float(key)
@@ -1214,7 +1199,7 @@ def plot_time_series(self, comp_var: Iterable[str | tuple[str, str]], title: str
Args:
comp_var (Iterable): Iterable of (, ) tuples (as used in retrieve)
- Alternatively, the jspath syntax . is also accepted
+ Alternatively, the json_path syntax . is also accepted
title (str): optional title of the plot
"""
data: TDataTable = self.retrieve(comp_var)
@@ -1246,7 +1231,7 @@ def plot_time_series(self, comp_var: Iterable[str | tuple[str, str]], title: str
assert all(type[v] is type[_values[0]] for v in _values), (
f"values of variable {label} have non-uniform types: {_values}"
)
- values: TDataColumn = cast(TDataColumn, _values)
+ values: TDataColumn = cast("TDataColumn", _values)
_ = plt.plot(times, values, label=_cv, linewidth=3)
if len(title):
diff --git a/src/sim_explorer/cli/__main__.py b/src/sim_explorer/cli/__main__.py
index 38a8a09..6dc382d 100644
--- a/src/sim_explorer/cli/__main__.py
+++ b/src/sim_explorer/cli/__main__.py
@@ -4,21 +4,12 @@
import argparse
import importlib.metadata
import logging
-import sys
from pathlib import Path
from sim_explorer.case import Case, Cases
from sim_explorer.cli.display_results import group_assertion_results, log_assertion_results
from sim_explorer.utils.logging import configure_logging
-# Remove current directory from Python search path.
-# Only through this trick it is possible that the current CLI file 'sim_explorer.py'
-# carries the same name as the package 'sim_explorer' we import from in the next lines.
-# If we did NOT remove the current directory from the Python search path,
-# Python would start searching for the imported names within the current file (sim_explorer.py)
-# instead of the package 'sim_explorer' (and the import statements fail).
-sys.path = [path for path in sys.path if Path(path) != Path(__file__).parent]
-
logger = logging.getLogger(__name__)
@@ -134,21 +125,22 @@ def main() -> None:
log_level_file: str = args.log_level
configure_logging(log_level_console, log_file, log_level_file)
- cases_path: Path = Path(args.cases)
+ cases_file: Path = Path(args.cases)
# Check whether sim-explorer cases file exists
- if not cases_path.is_file():
- logger.error(f"sim-explorer.py: File {cases_path} not found.")
+ if not cases_file.is_file():
+ logger.error(f"sim-explorer.py: File {cases_file} not found.")
return
+
logger.info(f"ARGS: {args}")
+ log_msg_stub: str = f"Start sim-explorer.py with following arguments:\n\t cases: \t{args.cases}\n"
+
try:
cases = Cases(args.cases)
except Exception:
logger.exception(f"Instantiation of {args.cases} not successfull")
return
- log_msg_stub: str = f"Start sim-explorer.py with following arguments:\n\t cases: \t{cases}\n"
-
case: Case | None = None
if args.info is not None and args.info:
diff --git a/src/sim_explorer/json5.py b/src/sim_explorer/json5.py
deleted file mode 100644
index 224e871..0000000
--- a/src/sim_explorer/json5.py
+++ /dev/null
@@ -1,664 +0,0 @@
-"""Python module for working with json5 files."""
-
-# ruff: noqa: ERA001
-
-from __future__ import annotations
-
-import contextlib
-import logging
-import re
-from pathlib import Path
-from typing import TYPE_CHECKING, Any, TypeVar, overload
-
-from jsonpath_ng.exceptions import JsonPathParserError
-from jsonpath_ng.ext import parse
-from jsonpath_ng.jsonpath import DatumInContext
-
-if TYPE_CHECKING:
- import os
- from collections.abc import Sequence
-
-logger = logging.getLogger(__name__)
-
-
-class Json5Error(Exception):
- """Special error indicating that something was not conformant to json5 code."""
-
-
-class Json5:
- r"""Work with json5 files (e.g. cases specification and results).
-
- * Read Json5 code from file, string or dict, representing the result internally as Python code (dict of dicts,lists,values)
- * Searching for elements using JsonPath expressions
- * Some Json manipulation methods
- * Write Json5 code to file
-
- Args:
- js5 (Path,str): Path to json5 file or json5 string
- auto (bool)=True: Determine whether running to_py automatically
- comments_eol (tuple)= ('//', '#') : tuple of end-of-line comment strings which shall be recognised
- comments_ml (tuple)= ('/\*', "'''") : tuple of multi-line comment strings which shall be recognised.
- End of comment is always the reversed of the start of comment.
- Double-quote ml comments are also supported per default
- """
-
- __slots__ = (
- "comments",
- "comments_eol",
- "comments_ml",
- "js5",
- "js_py",
- "lines",
- "pos",
- )
-
- def __init__(
- self,
- js5: str | os.PathLike[str] | dict[str, Any],
- *,
- auto: bool | int = True,
- comments_eol: tuple[str, ...] = ("//", "#"),
- comments_ml: tuple[str, ...] = ("/*", "'" * 3, '"' * 3),
- ) -> None:
- self.pos: int = 0
- self.comments_eol: tuple[str, ...] = comments_eol
- self.comments_ml: tuple[str, ...] = comments_ml
- self.js_py: dict[str, Any] = {}
- self.js5: str = ""
- if isinstance(js5, dict): # instantiation from dict
- assert self.check_valid_js(js5), f"{js5} is not a valid Json dict"
- self.js_py = js5
- self.js5 = ""
- else: # instantiation from file
- with contextlib.suppress(Exception):
- if Path(js5).exists():
- path = Path(js5)
- elif Path(Path(js5).name).exists():
- path = Path(Path(js5).name)
- self.js5 = path.read_text()
- if not self.js5: # file reading not succesfull
- if isinstance(js5, str):
- self.js5 = js5
- else:
- raise Json5Error(f"Invalid Json5 input {self.js5}") from None
- if self.js5[0] != "{":
- self.js5 = "{\n" + self.js5
- if self.js5[-1] != "}":
- self.js5 = self.js5 + "\n}"
- self.js5, self.lines = self._lines() # map the lines first so that error messages work
- self.js5, self.comments = self._comments()
- self.js5, _ = self._newline() # replace unnecessary LFs and return start position per line
- self.js_py = {} # is replaced by the python json5 dict when to_py() is run
- if auto:
- self.js_py = self.to_py()
-
- def _msg(self, pre: str, num: int = 50, pos: int | None = None) -> str:
- """Construct an error message from pre and a citation from the raw json5 code.
-
- The citation is from 'pos' with 'num' characters.
- Used mostly for reporting reader errors.
- """
- if pos is None:
- pos = self.pos
- try:
- line, p = self._get_line_number(pos)
- return f"Json5 read error at {line}({p}): {pre}: {self.js5[pos : pos + num]}"
- except Json5Error as err: # can happen when self.lines does not yet exist
- return f"Json5 read error at {pos}: {pre}: {self.js5[pos : pos + num]}: {err}"
-
- def _lines(self) -> tuple[str, list[int]]:
- """Map start positions of lines and replace all newline CR-LF combinations with single newline (LF)."""
- c: re.Pattern[str] = re.compile(r"\n\r|\r\n|\r|\n")
- pos: int = 0
- lines: list[int] = [0]
- js: str = ""
- s: re.Match[str] | None
- while s := c.search(self.js5[pos:]):
- js += self.js5[pos : pos + s.start()] + "\n"
- lines.append(len(js)) # register line start
- pos += s.end()
- return (js + self.js5[pos:], lines)
-
- def _newline(self) -> tuple[str, list[int]]:
- """Replace unnecessary line feeds with spaces and return list of start position per line."""
- qt1: int = 0 # single quote state
- qt2: int = 0 # double quote state
- c: re.Pattern[str] = re.compile(r'"|\'|\n\r|\r\n|\r|\n')
- pos: int = 0
- lines: list[int] = [0]
- js: str = ""
- s: re.Match[str] | None
- while s := c.search(self.js5[pos:]):
- js += self.js5[pos : pos + s.start()]
- if s.group() == '"' and not qt1:
- qt2 = 1 - qt2
- js += s.group()
- elif s.group() == "'" and not qt2:
- qt1 = 1 - qt1
- js += s.group()
- else:
- lines.append(pos + s.end()) # register line start (also if within literal string)
- if qt1 or qt2: # We are within a literal string. -> Keep newlines.
- js += s.group()
- elif s.group() in ("\n\r", "\r\n"): # Remove newlines.
- js += " "
- elif s.group() in ("\r", "\n"): # Remove newlines.
- js += " "
- pos += s.end()
-
- if qt1 + qt2 != 0:
- _ = self._msg("Non-matching quotes detected")
- return (js + self.js5[pos:], lines)
-
- def _get_line_number(self, pos: int) -> tuple[int, int]:
- """Get the line number relative to position 'pos'.
- Returns both the row and column of 'pos' (1-based).
- """
- return next( # line number (zero-based) and position at beginning of line
- ((i, pos - self.lines[i - 1] + 1) for i, p in enumerate(self.lines) if p > pos),
- (len(self.lines), pos - self.lines[-1] + 1),
- )
-
- def line(self, num: int) -> str:
- """Return the raw json5 line 'num'.
-
- Args:
- num (int): the line number of the line to retrieve (zero-based).
- 'num' works here like python indexes, starting from 0 and also working with negative numbers!
- """
- L = len(self.lines)
- if num in [-1, L - 1]:
- return self.js5[self.lines[-1] :].strip()
- if -L + 1 < num < -1:
- return self.js5[L + num : L + num + 1]
- if len(self.lines) > num - 1:
- return self.js5[self.lines[num] : self.lines[num + 1]].strip()
- return ""
-
- def _comments(self, js5: str = "") -> tuple[str, dict[int, str]]:
- """Take the raw json5 text 'js5' (default: self.js5) as input and replace comments with whitespace.
-
- Both comments_eol and comment_ml are taken into account as initialized.
- Leave the line breaks intact, so that line counting is not disturbed.
- Return the resulting 'cleaned' string and the comments dict
- """
-
- def _re(txt: str) -> str:
- return "".join("\\" + ch if ch in ("*",) else ch for ch in txt)
-
- js5_without_comments: str = js5 or self.js5
- comments: dict[int, str] = {}
- cq: re.Pattern[str] = re.compile(r"'([^']*)'") # single quotes
- cq2: re.Pattern[str] = re.compile(r'"([^"]*)"') # double quotes
- _js5: str
- pos: int
-
- for cmt in self.comments_eol: # handle end-of-line comments
- _js5 = js5_without_comments
- js5_without_comments = ""
- c: re.Pattern[str] = re.compile(pattern=f"{cmt}.*$", flags=re.MULTILINE) # eol comments
- pos = 0
- s: re.Match[str] | None
- while s := c.search(string=_js5[pos:]):
- sq = cq.search(string=_js5[pos:])
- sq2 = cq2.search(string=_js5[pos:])
- # print("_COMMENTS", pos, s, sq, sq2)
- if (sq is None or s.start() < sq.start() or s.start() > sq.end()) and (
- sq2 is None or s.start() < sq2.start() or s.start() > sq2.end()
- ):
- # no quote or comments starts before or after quote. Handle comment
- comments[pos + s.start()] = s.group()
- js5_without_comments += _js5[pos : pos + s.start()]
- js5_without_comments += " " * len(s.group())
- pos += s.end()
- elif sq is not None and sq.start() < s.start() < sq.end():
- # Comment sign within single quotes. Leave alone
- js5_without_comments += _js5[pos : pos + sq.end()]
- pos += sq.end()
- elif sq2 is not None and sq2.start() < s.start() < sq2.end():
- # Comment sign within double quotes. Leave alone
- js5_without_comments += _js5[pos : pos + sq2.end()]
- pos += sq2.end()
- else:
- raise Json5Error(f"Unhandled EOL-comment removal: {s}, {sq}, {sq2}")
- js5_without_comments += _js5[pos:]
- """
- if (
- s is None
- or (sq is not None and sq.end() < s.start())
- or (sq2 is not None and sq2.end() < s.start())
- ):
- _js5_without_comments += _js5[pos:]
- break
- if (s is not None and
- (sq is None or sq.start() > s.start() or s.start() > sq.end()) and
- (sq2 is None or sq2.start() > s.start() or s.start() > sq2.end())): # comment sign outside quotes
- comments.update({pos + s.start(): s.group()})
- _js5_without_comments += _js5[pos : pos + s.start()]
- _js5_without_comments += " " * len(s.group())
- pos += s.end()
- elif sq is not None:
- _js5_without_comments += _js5[pos : sq.end()]
- pos += sq.end()
- elif sq2 is not None:
- _js5_without_comments += _js5[pos : sq2.end()]
- pos += sq2.end()
- else:
- raise Json5Error(f"Unresolved when removing comments {_js5[pos:]}") from None
- """
-
- for cmt in self.comments_ml: # handle multi-line comments
- _js5 = js5_without_comments
- js5_without_comments = ""
- c1: re.Pattern[str] = re.compile(f"{_re(cmt)}")
- c2: re.Pattern[str] = re.compile(f"{_re(cmt[::-1])}")
- pos = 0
- s1: re.Match[str] | None
- while s1 := c1.search(_js5[pos:]):
- sq = cq.search(_js5[pos:])
- sq2 = cq2.search(_js5[pos:])
- js5_without_comments += _js5[pos : pos + s1.start()]
- pos += pos + s1.start()
- s2 = c2.search(_js5[pos:])
- assert s2 is not None, f"No end of comment found for comment starting with '{_js5[pos : pos + 50]}'"
- comments[pos + s2.start()] = _js5[pos : pos + s2.start()]
- for p in range(pos, pos + s2.end()):
- js5_without_comments += " " if _js5[p] not in ("\r", "\n") else _js5[p]
- pos += s2.end()
- js5_without_comments += _js5[pos:]
-
- return js5_without_comments, comments
-
- def to_py(self) -> dict[str, Any]:
- """Translate json5 code 'self.js5' to a python dict and store as self.js_py."""
- self.pos = 0
- return self._object()
-
- def _strip(self, txt: str) -> str:
- """Strip white space from txt."""
- if not txt:
- return txt
- len0 = len(txt)
- while True:
- txt = txt.strip()
- if len(txt) == len0:
- return txt
- len0 = len(txt)
-
- def _object(self) -> dict[str, Any]:
- """Start reading a json5 object { ... } at current position."""
- # print(f"OBJECT({self.pos}): {self.js5[self.pos:]}")
- assert self.js5[self.pos] == "{", self._msg("object start '{' expected")
- self.pos += 1
- dct: dict[str, Any] | None = None
- r0: int
- c0: int
- k: str
- v: int | float | str | dict[str, Any] | list[Any]
- while True:
- r0, c0 = self._get_line_number(self.pos)
- k = self._key() # read until ':'
- v = self._value() # read until ',' or '}'
- # print(f"KEY:VALUE {k}:{v}. {r0}({c0}): '{self.js5[self.lines[r0-1]+c0 : self.lines[r0-1]+c0+50]+'...'}'")
- if k == "" and v == "" and self.js5[self.pos] == "}":
- self.pos += 1
- assert dct is not None, f"Cannot extract js5 object from {self.js5}"
- return dct
- assert k != "", self._msg(f"No proper key: {k}:{v} within object.")
- assert v != "", self._msg(f"No proper value: {k}:{v} within object.")
- assert dct is None or k not in dct, self._msg(
- f"Duplicate key '{k}' within object starting at line {r0}({c0}). Not allowed."
- )
- if dct is None:
- dct = {k: v}
- else:
- dct.update({k: v})
-
- def _list(self) -> list[Any]:
- """Read and return a list object at the current position."""
- # print(f"LIST({self.pos}): {self.js5[self.pos:]}")
- assert self.js5[self.pos] == "[", self._msg("List start '[' expected")
- self.pos += 1
- lst = []
- while True:
- v = self._value()
- # print("LIST_VALUE", v, self.js5[self.pos])
- if v != "":
- lst.append(v)
- elif self.js5[self.pos] == "]":
- break
- assert self.js5[self.pos] == "]", self._msg("List end ']' expected")
- self.pos += 1
- return lst
-
- def _quoted(self, pos: int | None = None) -> tuple[int, int]:
- """Search for a string between quotes after pos ('...' or "...") with no other text before the first quote.
-
- Return the absolute position of the quote pair as tuple,
- such that self.js5[q1:q2] represents the quoted string with quotes, or (None,None).
- Note that the absolute position of the right quote is m2.start()=q2-1!
- """
- if pos is None:
- pos = self.pos
- m = re.search(r"'|\"", self.js5[pos:])
- if m is None or len(
- self.js5[pos : pos + m.start()].strip()
- ): # non-white space before the quote is unacceptable
- return (-1, -1)
- m2 = re.search(m.group(), self.js5[pos + m.end() :])
- if m2 is None: # sourcery skip: assign-if-exp, reintroduce-else
- return (-1, -1)
- return (pos + m.start(), pos + m.end() + m2.end())
-
- def _key(self) -> str:
- """Read and return a key at the current position, i.e. expect ':'.
-
- Due to the fact that trailing ',' are allowed,
- we might find '}' or end of string, denoting an empty key/end of object.
- """
- q1, q2 = self._quoted()
- if q1 >= 0: # found a quoted string
- self.pos = q2
- k = self.js5[q1 + 1 : q2 - 1]
- # print("QUOTED KEY", k, self.js5[self.pos :])
- m = re.search(r":", self.js5[self.pos :])
- assert m is not None, self._msg(f"Quoted key {k} found, but no ':'")
- assert not len(self.js5[self.pos : self.pos + m.start()].strip()), self._msg(
- f"Additional text '{self.js5[self.pos : self.pos + m.start()].strip()}' after key '{k}'"
- )
- else:
- m = re.search(r"[:\}]", self.js5[self.pos :])
- # print("KEY", self.pos, self.js5[self.pos : self.pos+50], m)
- assert m is not None, self._msg("key expected")
- if m.group() == "}": # end of object, e.g. due to trailing ','
- return ""
- k = self.js5[self.pos : self.pos + m.start()]
- self.pos += m.end()
- return str(self._strip(k))
-
- def _value(self) -> int | float | str | dict[str, Any] | list[Any]: # noqa: C901, PLR0911, PLR0912
- """Read and return a value at the current position, i.e. expect ,'...', "...",}."""
- v: str | dict[str, Any] | list[Any]
- q1, q2 = self._quoted()
- m: re.Match[str] | None = None
- if q2 < 0: # no quotation found. Include also [ and { in search
- m = re.search(r"[\[,\{\}\]]", self.js5[self.pos :])
- else: # quoted value. Should find , ] or } after the value
- self.pos = q2
- m = re.search(r"[,\}\]]", self.js5[self.pos :])
- # print("Found quoted", self.js5[q1:q2], m)
- assert m is not None, self._msg("value expected")
- if m.group() in ("{", "["): # found an object or a list start (quotation not allowed!)
- assert ":" not in self.js5[self.pos : self.pos + m.start()], self._msg("Found ':'. Forgot ','?")
- self.pos += m.start()
- v = self._object() if m.group() == "{" else self._list()
- m = re.search(r"[,\}\]]", self.js5[self.pos :])
- cr, cc = self._get_line_number(self.pos)
- assert m is not None, self._msg(f"End of value or end of object/list '{str(v)[:50]}..' expected")
- elif m.group() in ("]", "}", ","): # any allowed value separator (also last list/object value)
- v = self.js5[self.pos : self.pos + m.start()].strip() if q2 < 0 else self.js5[q1 + 1 : q2 - 1]
- else:
- raise Json5Error(
- f"Unhandled situation. Quoted: ({q1 - self.pos},{q2 - self.pos}), search: {m}. From pos: {self.js5[self.pos :]}"
- )
- # leave the '}', ']', but make sure that ',' is eaten
- self.pos += m.start() if m.group() in ("}", "]") else m.end()
-
- if isinstance(v, str):
- v = v.strip().strip("'").strip('"').strip()
- if q2 < 0: # no quotation was used. Key separator not allowed.
- assert ":" not in v, self._msg(f"Key separator ':' in value: {v}. Forgot ','?")
-
- if isinstance(v, dict | list):
- return v
- if not v: # might be an empty string due to trailing ','
- return ""
-
- if q2 >= 0: # explicitly quoted values are treated as strings!
- return str(v)
-
- try:
- return int(v)
- except Exception: # noqa: BLE001
- try:
- return float(v)
- except Exception: # noqa: BLE001
- # sourcery skip: assign-if-exp, reintroduce-else
- if v.upper() == "FALSE":
- return False
- if v.upper() == "TRUE":
- return True
- if v.upper() == "INFINITY":
- return float("inf")
- if v.upper() == "-INFINITY":
- return float("-inf")
- return str(v)
-
- _VT = TypeVar("_VT", bound=Any)
-
- @overload
- def jspath(
- self,
- path: str,
- typ: type[_VT],
- *,
- error_msg: bool = False,
- ) -> _VT | None: ...
-
- @overload
- def jspath(
- self,
- path: str,
- typ: None = None,
- *,
- error_msg: bool = False,
- ) -> Any | None: # noqa: ANN401
- ...
-
- def jspath(
- self,
- path: str,
- typ: type[_VT] | None = None,
- *,
- error_msg: bool = False,
- ) -> _VT | Any | None:
- r"""Evaluate a JsonPath expression on the Json5 code and return the result.
-
- Syntax see `RFC9535 `_
- and `jsonpath-ng (used here) `_
-
- * $: root node identifier (Section 2.2)
- * @: current node identifier (Section 2.3.5) (valid only within filter selectors)
- * []: child segment (Section 2.5.1): selects zero or more children of a node
- * .name: shorthand for ['name']
- * .\*: shorthand for [*]
- * ..[]: descendant segment (Section 2.5.2): selects zero or more descendants of a node
- * ..name: shorthand for ..['name']
- * ..\*: shorthand for ..[*]
- * 'name': name selector (Section 2.3.1): selects a named child of an object
- * \*: wildcard selector (Section 2.3.2): selects all children of a node
- * i: (int) index selector (Section 2.3.3): selects an indexed child of an array (from 0)
- * 0:100:5: array slice selector (Section 2.3.4): start:end:step for arrays
- * ?: filter selector (Section 2.3.5): selects particular children using a logical expression
- * length(@.foo): function extension (Section 2.4): invokes a function in a filter expression
-
- Args:
- path (str): path expression as string.
- typ (type)=None: optional specification of the expected type to find
- errMsg (bool)=False: specify whether an error should be raised, or None returned (default)
- """
- try:
- compiled = parse(path)
- except JsonPathParserError as e:
- raise ValueError(f"Invalid JsonPath expression: {path}\n{e}") from e
- data: Sequence[Any] = compiled.find(self.js_py)
- # print("DATA", data)
- val: Any | list[Any] | None = None
- msg: str = ""
- if not len(data): # not found
- msg = f"No match for {path}"
- elif len(data) == 1: # found a single element
- val = data[0].value
- elif isinstance(data[0], DatumInContext):
- val = [x.value for x in data]
-
- if val is not None and typ is not None and not isinstance(val, typ):
- try: # try to convert
- val = typ(val)
- except Exception: # noqa: BLE001
- msg = f"{path} matches, but type {typ} does not match {type(val)}."
- val = None
- if val is None and error_msg:
- raise ValueError(msg)
- return val
-
- @staticmethod
- def _spath_to_keys(spath: str) -> list[str]:
- """Extract the keys from path.
- So far this is a minimum implementation for adding data. Probably this could be done using jsonpath-ng.
- """
- keys: list[str] = []
- spath = spath.lstrip("$.")
- if spath.startswith("$["):
- spath = spath[1:]
- c: re.Pattern[str] = re.compile(r"\[(.*?)\]")
- while m := c.search(spath):
- if m.start() > 0:
- keys.extend(spath[: m.start()].split("."))
- keys.append(spath[m.start() + 1 : m.end() - 1])
- spath = spath[m.end() :]
- if len(spath.strip()):
- keys.extend(spath.split("."))
- return keys
-
- @staticmethod
- def check_valid_js(
- js_py: dict[str, Any] | Any, # noqa: ANN401
- ) -> bool:
- """Check whether the dict js_py is a valid Json dict."""
-
- def check_valid_js_list(lst: list[Any]) -> bool:
- for itm in lst:
- if isinstance(itm, dict):
- return Json5.check_valid_js(itm)
- if isinstance(itm, list):
- return check_valid_js_list(itm)
- # accept as Json atom
- return True
-
- if not isinstance(js_py, dict):
- logger.warning(f"Not a (sub-)dict. Found type {type(js_py)}: {js_py}")
- return False
- for k, v in js_py.items():
- if not isinstance(k, str):
- logger.error(f"Key {k} is not a string. (sub-)dict:{js_py}")
- return False
- if isinstance(v, dict) and not Json5.check_valid_js(js_py=v):
- logger.error(f"Not a valid Json dict: {v}")
- return False
- if isinstance(v, list) and not check_valid_js_list(lst=v):
- logger.error(f"Not a valid Json list: {v}")
- return False
- # accept as atom
- return True
-
- def update(
- self,
- spath: str,
- data: dict[str, Any] | list[Any] | Any, # noqa: ANN401
- ) -> None:
- """Append data to the js_py dict at the path pointed to by keys.
- So far this is a minimum implementation for adding data. Probably this could be done using jysonpath-ng.
- """
-
- keys: list[str] = Json5._spath_to_keys(spath)
- path: dict[str, Any] | list[Any] | Any = self.js_py
- parent: dict[str, Any] | list[Any] | Any = self.js_py
- for i, k in enumerate(keys):
- if k not in path:
- for j in range(len(keys) - 1, i - 1, -1):
- data = {keys[j]: data}
- break
- parent = path
- # NOTE: `assert` is necessary as `path[k]` will be an invalid get operation if `path` is not a dict.
- # TODO @EisDNV: Check and possibly improve code to allow accessing also indexed elements in lists.
- # ClaasRostock, 2025-01-26.
- assert isinstance(path, dict)
- path = path[k]
- # print(f"UPDATE path:{path}, parent:{parent}, k:{k}: {data}")
- if isinstance(path, list):
- path.append(data)
- elif isinstance(path, dict):
- path.update(data)
- elif isinstance(parent, dict): # update the parent dict (replace a value)
- parent.update({k: data})
-
- def write( # noqa: C901
- self,
- file: str | os.PathLike[str] | None = None,
- *,
- pretty_print: bool = True,
- ) -> str:
- """Write a Json(5) tree to string or file.
-
- Args:
- file (str, Path)=None: The file name (as string or Path object) or None. If None, a string is returned.
- pretty_print (bool)=True: Denote whether the string/file should be pretty printed (LF,indents).
-
- Returns: The serialized Json(5) object as string. This string is optionally written to file.
- """
-
- def remove_comma(txt: str) -> str:
- for i in range(len(txt) - 1, -1, -1):
- if txt[i] == ",":
- return txt[:i]
- return ""
-
- def print_js5(
- sub: dict[str, Any] | list[Any] | Any, # noqa: ANN401
- level: int = 0,
- *,
- pretty: bool = True,
- ) -> str:
- """Print the Json5 object recursively. Return the formated string.
-
- Args:
- sub (dict): the Json5 object to print
- level (int)=0: level in recursive printing. Used for indentation.
- pretty (bool)=True: Pretty print (LF and indentation).
- """
- if isinstance(sub, dict):
- res = "{"
- for k, v in sub.items(): # print the keys and values of dicts
- res += "\n" + " " * level if pretty else ""
- res += " " * level if pretty else ""
- res += str(k)
- res += " : " if pretty else ":"
- res += print_js5(sub=v, level=level + 1, pretty=pretty)
- res += "\n" + " " * level if pretty else ""
- res = remove_comma(res)
- res += "}," if level > 0 else "}"
- res += "\n" if pretty else ""
- elif isinstance(sub, list):
- res = "["
- for v in sub:
- sub_res = print_js5(sub=v, level=level, pretty=pretty)
- res += sub_res or ""
- res = remove_comma(res)
- res += "],"
- res += "\n" if pretty else ""
- elif sub == "":
- res = ","
- elif isinstance(sub, str):
- res = f"'{sub!s}',"
- elif isinstance(sub, int | float | bool):
- res = f"{sub!s},"
- else: # try still to make a string
- res = f"{sub!s},"
- return res
-
- js5 = print_js5(self.js_py, level=0, pretty=pretty_print)
- if file:
- with Path(file).open(mode="w") as fp:
- _ = fp.write(js5)
- return js5
diff --git a/src/sim_explorer/models.py b/src/sim_explorer/models.py
index caa4770..33e3da5 100644
--- a/src/sim_explorer/models.py
+++ b/src/sim_explorer/models.py
@@ -8,7 +8,7 @@ class Temporal(IntEnum):
A = 1
ALWAYS = 1
F = 2
- FINALLY = 2
+ EVENTUALLY = 2
T = 3
TIME = 3
diff --git a/src/sim_explorer/system_interface.py b/src/sim_explorer/system_interface.py
index 5cdb651..90858bd 100644
--- a/src/sim_explorer/system_interface.py
+++ b/src/sim_explorer/system_interface.py
@@ -7,11 +7,11 @@
from collections.abc import Callable, Generator, Sequence
from enum import Enum
from pathlib import Path
-from typing import TYPE_CHECKING, Any, cast
+from typing import TYPE_CHECKING, Any, SupportsFloat, cast
import numpy as np
-from sim_explorer.json5 import Json5
+from sim_explorer.utils.json5 import json5_read
from sim_explorer.utils.misc import from_xml, match_with_wildcard
from sim_explorer.utils.osp import read_system_structure_xml
from sim_explorer.utils.types import TActionArgs, TGetActionArgs, TSetActionArgs, TValue
@@ -87,12 +87,12 @@ def read_system_structure(
-------
The system structure as (json) dict as if the structure was read through osp_system_structure_from_js5
"""
- system_structure: dict[str, Any] | Json5
+ system_structure: dict[str, Any]
assert file.exists(), f"System structure {file} not found"
if file.suffix == ".xml": # assume the standard OspSystemStructure.xml file
system_structure = read_system_structure_xml(file)
elif file.suffix in (".js5", ".json"): # assume the js5 variant of the OspSystemStructure
- system_structure = Json5(file).js_py
+ system_structure = json5_read(file)
elif file.suffix == ".ssp":
# see https://ssp-standard.org/publications/SSP10/SystemStructureAndParameterization10.pdf
raise NotImplementedError("The SSP file variant is not yet implemented") from None
@@ -145,7 +145,7 @@ def match_components(self, comps: str | tuple[str, ...]) -> tuple[str, tuple[str
if m == model and k not in collect:
collect.append(k)
assert model is not None, f"No model match for {comps}"
- assert len(collect), f"No component match for {comps}"
+ assert collect, f"No component match for {comps}"
return (model, tuple(collect))
def _get_variables(self, source: Path) -> dict[str, dict[int | str, Any]]:
@@ -313,15 +313,14 @@ def pytype(fmu_type: str, val: TValue | None = None) -> type | bool:
return typ(val)
@staticmethod
- def default_initial(
+ def valid_initial(
causality: str,
variability: str,
- *,
- only_default: bool = True,
- ) -> str | int | tuple[int] | tuple[str, ...]:
- """Return default initial setting as str. See p.50 FMI2.
- With only_default, the single allowed value, or '' is returned.
- Otherwise a tuple of possible values is returned where the default value is always listed first.
+ ) -> tuple[str, ...]:
+ """Return valid initial setting as tuple of str. See p.50 FMI2.
+ The default value is always listed first in the tuple.
+ The empty string denotes 'no initial setting'.
+ 'ERROR' denotes that the combination causality/variability is invalid.
"""
col: int = {
"parameter": 0,
@@ -347,16 +346,20 @@ def default_initial(
(-2, -2, 5, 8, 13, -3),
(-2, -2, 6, 9, 14, 15),
)[row][col]
-
+ res: tuple[str, ...]
if init < 0: # "Unallowed combination {variability}, {causality}. See '{chr(96-init)}' in FMI standard"
- return init if only_default else (init,)
- if init in {1, 2, 7, 10}:
- return "exact" if only_default else ("exact",)
- if init in {3, 4, 11, 12}:
- return "calculated" if only_default else ("calculated", "approx")
- if init in {8, 9, 13, 14}:
- return "calculated" if only_default else ("calculated", "exact", "approx")
- return init if only_default else (init,)
+ res = (f"ERROR_{chr(96 - init)}",)
+ elif init in {1, 2, 7, 10}:
+ res = ("exact",)
+ elif init in {3, 4, 11, 12}:
+ res = ("calculated", "approx")
+ elif init in {8, 9, 13, 14}:
+ res = ("calculated", "exact", "approx")
+ elif init in {5, 6, 15}: # combination valid, but initial shall not be provided
+ res = ("",)
+ else:
+ raise ValueError(f"Unknown init index {init}") from None
+ return res
def allowed_action( # noqa: C901
self,
@@ -367,14 +370,18 @@ def allowed_action( # noqa: C901
) -> bool:
"""Check whether the action would be allowed according to FMI2 rules, see FMI2.01, p.49.
- * if a tuple of variables is provided, the variables shall have equal properties
- in addition to the normal allowed rules.
+ Note: If a tuple of variables is provided, the variables shall have equal properties
+ in addition to the normal allowed rules.
Args:
action (str): Action type, 'set', 'get', including init actions (set at time 0)
comp (int,str): The instantiated component within the system (as index or name)
- var (int,str,tuple): The variable(s) (of component) as reference or name
+ var (int,str,Sequence[int], Sequence[str]): The variable(s) (of component) as reference or name
time (float): The time at which the action will be performed
+
+ Returns
+ -------
+ True if the action is allowed, False otherwise. In case of False, self.message contains the reason.
"""
def _description(
@@ -393,15 +400,20 @@ def _check(*, cond: bool, msg: str) -> bool:
return False
return True
- _type, _causality, _variability = ("", "", "") # unknown
+ _type, _causality, _variability, _initial = ("", "", "", "") # unknown
variables = self.variables(comp)
for name, var_info in self.variable_iter(variables=variables, flt=var):
+ assert isinstance(name, str), "str expected. Found {name}"
+ assert isinstance(var_info, dict), f"Dict expected as var_info. Found {var_info}"
if _type == "" or _causality == "" or _variability == "": # define the properties and check whether allowed
_type = var_info["type"]
_causality = var_info["causality"]
_variability = var_info["variability"]
- _initial = var_info.get("initial", SystemInterface.default_initial(_causality, _variability))
+ _initial = var_info.get("initial", SystemInterface.valid_initial(_causality, _variability)[0])
+ assert not _initial.startswith("ERROR"), (
+ f"Invalid combination of causality {_causality}-variability {_variability}: {_initial}"
+ )
if action in {"get", "step"}: # no restrictions on get
pass
elif action == "set" and (
@@ -430,7 +442,7 @@ def _check(*, cond: bool, msg: str) -> bool:
return False
# additional rule for ModelExchange, not listed here
else: # check whether the properties are equal
- _initial = var_info.get("initial", SystemInterface.default_initial(_causality, _variability))
+ _initial = var_info.get("initial", SystemInterface.valid_initial(_causality, _variability))
if not _check(
cond=_type == var_info["type"],
msg=f"{_description(name=name, info=var_info, initial=_initial)} != type {_type}",
@@ -573,9 +585,9 @@ def add_actions( # noqa: PLR0913
act_type: str,
cvar: str,
cvar_info: dict[str, Any],
- values: tuple[TValue, ...] | None,
- at_time: float,
- stoptime: float,
+ values: Sequence[TValue] | None,
+ at_time: SupportsFloat,
+ stoptime: SupportsFloat,
rng: tuple[int, ...] | None = None,
) -> None:
"""Add specified actions to the provided action dict.
@@ -588,8 +600,8 @@ def add_actions( # noqa: PLR0913
cvar_info (dict): dict of variable info: {model, instances, names, refs, type, causality, variability}
see Cases.get_case_variables() for details.
values (TValue) = None: Optional values (mandatory for 'set' actions)
- at_time (float): time at which actions shall be triggered (may be scaled)
- stoptime (float): simulation stop time (needed to handle 'step' actions)
+ at_time (SupportsFloat): time at which actions shall be triggered (may be scaled)
+ stoptime (SupportsFloat): simulation stop time (needed to handle 'step' actions)
rng (Iterable)=None: Optional range specification for compound variables (indices to address)
Returns
@@ -599,7 +611,18 @@ def add_actions( # noqa: PLR0913
where value-list and rng are only present for set actions
at-time=-1 for get actions denote step actions
"""
- assert isinstance(at_time, float | int), f"Actions require a defined time as float. Found {at_time}"
+ try:
+ at_time = float(at_time)
+ except Exception as e:
+ raise ValueError(
+ f"Parameter `at_time` must be a float. Value {at_time} could not be converted to float."
+ ) from e
+ try:
+ stoptime = float(stoptime)
+ except Exception as e:
+ raise ValueError(
+ f"Parameter `stoptime` must be a float. Value {stoptime} could not be converted to float."
+ ) from e
if at_time not in actions:
actions[at_time] = [] # make sure that there is a suitable slot
for comp in cvar_info["instances"]:
@@ -608,7 +631,7 @@ def add_actions( # noqa: PLR0913
"Get actions must be tuples of (cvar, comp, refs)"
)
self._add_get(
- actions=cast(dict[float, list[TGetActionArgs]], actions),
+ actions=cast("dict[float, list[TGetActionArgs]]", actions),
time=at_time,
cvar=cvar,
comp=comp,
@@ -619,9 +642,9 @@ def add_actions( # noqa: PLR0913
assert all(len(args) == 3 for t in actions for args in actions[t]), ( # noqa: PLR2004
"Get actions must be tuples of (cvar, comp, refs)"
)
- for time in np.arange(start=at_time, stop=stoptime, step=at_time):
+ for time in np.linspace(start=at_time, stop=stoptime, num=int(stoptime / at_time) + 1):
self._add_get(
- actions=cast(dict[float, list[TGetActionArgs]], actions),
+ actions=cast("dict[float, list[TGetActionArgs]]", actions),
time=time,
cvar=cvar,
comp=comp,
@@ -635,7 +658,7 @@ def add_actions( # noqa: PLR0913
"Get actions must be tuples of (cvar, comp, refs, values)"
)
self._add_set(
- actions=cast(dict[float, list[TSetActionArgs]], actions),
+ actions=cast("dict[float, list[TSetActionArgs]]", actions),
time=at_time,
cvar=cvar,
comp=comp,
diff --git a/src/sim_explorer/system_interface_osp.py b/src/sim_explorer/system_interface_osp.py
index 1095f9b..d3e5faa 100644
--- a/src/sim_explorer/system_interface_osp.py
+++ b/src/sim_explorer/system_interface_osp.py
@@ -1,3 +1,4 @@
+import logging
from collections.abc import Callable
from functools import partial
from pathlib import Path
@@ -11,19 +12,21 @@
from sim_explorer.system_interface import SystemInterface
from sim_explorer.utils.types import TActionArgs
+logger = logging.getLogger(__name__)
+
class SystemInterfaceOSP(SystemInterface):
"""Implements the SystemInterface as a OSP.
Args:
- structure_file (Path): Path to system model definition file
- name (str)="System": Possibility to provide an explicit system name (if not provided by system file)
- description (str)="": Optional possibility to provide a system description
- log_level (str) = 'fatal': Per default the level is set to 'fatal',
- but it can be set to 'trace', 'debug', 'info', 'warning', 'error' or 'fatal' (e.g. for debugging purposes)
+ structure_file (Path): Path to system model definition file
+ name (str)="System": Possibility to provide an explicit system name (if not provided by system file)
+ description (str)="": Optional possibility to provide a system description
+ log_level (str) = 'fatal': Per default the level is set to 'fatal',
+ but it can be set to 'trace', 'debug', 'info', 'warning', 'error' or 'fatal' (e.g. for debugging purposes)
**kwargs: Optional possibility to supply additional keyword arguments:
- * full_simulator_available=True to overwrite the oposite when called from a superclass
+ Note: This class sets full_simulator_available=True , in contrast to the superclass where it is by default value set to False.
"""
def __init__(
@@ -91,7 +94,7 @@ def _action_func(self, act_type: int, var_type: type) -> Callable[..., Any]:
def do_action(self, time: int | float, act_info: TActionArgs, typ: type) -> bool:
"""Do the action described by the tuple using OSP functions."""
if len(act_info) == 4: # set action # noqa: PLR2004
- cvar, comp, refs, values = act_info
+ _cvar, comp, refs, values = act_info
_comp = self.component_id_from_name(comp)
if time <= 0: # initial setting
func = self._action_func(0, typ)
@@ -99,7 +102,7 @@ def do_action(self, time: int | float, act_info: TActionArgs, typ: type) -> bool
return self._action_func(1, typ)(_comp, refs, values)
# get action
- cvar, comp, refs = act_info
+ _cvar, comp, refs = act_info
_comp = self.component_id_from_name(comp)
assert time >= 0, "Get actions for all communication points shall be pre-compiled"
return self._action_func(2, typ)(_comp, refs)
@@ -109,7 +112,7 @@ def action_step(self, act_info: TActionArgs, typ: type) -> Callable[..., Any]:
so that it can be called at communication points.
"""
assert len(act_info) == 3, f"Exactly 3 arguments expected. Found {act_info}" # noqa: PLR2004
- cvar, comp, refs = act_info
+ _cvar, comp, refs = act_info
_comp = self.component_id_from_name(comp)
return partial(self._action_func(act_type=2, var_type=typ), _comp, refs)
diff --git a/src/sim_explorer/utils/codegen.py b/src/sim_explorer/utils/codegen.py
new file mode 100644
index 0000000..5396f87
--- /dev/null
+++ b/src/sim_explorer/utils/codegen.py
@@ -0,0 +1,24 @@
+from collections.abc import Callable
+from types import CodeType
+from typing import Any, cast
+
+
+def get_callable_function(
+ compiled: CodeType,
+ function_name: str,
+ global_ns: dict[str, Any] | None = None,
+ local_ns: dict[str, Any] | None = None,
+) -> Callable[..., Any]:
+ """Execute compiled code and return a named callable from the local namespace."""
+ globals_dict = global_ns if global_ns is not None else {}
+ locals_dict = local_ns if local_ns is not None else globals_dict
+ exec(compiled, globals_dict, locals_dict) # noqa: S102
+
+ if function_name not in locals_dict:
+ raise KeyError(f"Function '{function_name}' not found after execution")
+
+ func = locals_dict[function_name]
+ if not callable(func):
+ raise TypeError(f"Name '{function_name}' is not callable")
+
+ return cast("Callable[..., Any]", func)
diff --git a/src/sim_explorer/utils/json5.py b/src/sim_explorer/utils/json5.py
new file mode 100644
index 0000000..28569d8
--- /dev/null
+++ b/src/sim_explorer/utils/json5.py
@@ -0,0 +1,375 @@
+"""Python module for working with json5 files."""
+
+import codecs
+import logging
+import re
+from collections.abc import Sequence
+from pathlib import Path
+from typing import TYPE_CHECKING, Any, TypeVar, overload
+
+import pyjson5 as json5
+from jsonpath_ng.exceptions import JsonPathParserError
+from jsonpath_ng.ext import parse
+from pyjson5 import Json5Exception, Json5IllegalCharacter
+
+if TYPE_CHECKING:
+ from jsonpath_ng.jsonpath import DatumInContext
+
+logger = logging.getLogger(__name__)
+logging.basicConfig(format="%(levelname)s:%(message)s", level=logging.INFO)
+
+
+def get_pos(txt: str, start: str = "near ", end: str = ",") -> int:
+ pos0 = txt.find(start)
+ assert pos0 >= 0, f"String {start} not found in {txt}"
+ pos0 += 5
+ pos1 = txt.find(end, pos0)
+ assert pos1 >= 0, f"String {end} not found in {txt} after position {pos0}"
+ return int(txt[pos0:pos1])
+
+
+def json5_check(js5: dict[str, Any]) -> bool:
+ """Check whether the dict js5 can be interpreted as Json5. Wrapper function."""
+ return json5.encode_noop(js5)
+
+
+def json5_write( # noqa: C901, PLR0915
+ js5: dict[str, Any],
+ file: Path | str,
+ *,
+ indent: int = 3,
+ compact: bool = True,
+) -> None:
+ """Use pyjson5 to print the json5 code to file, optionally using indenting the code to make it human-readable.
+
+ Args:
+ file (Path | str): The file name (as string or Path object). The file is overwritten if it exists.
+ indent (int) = 3: indentation length. Raw dump if set to -1
+ compact (bool) = True: compact file writing, i.e. try to keep keys unquoted and avoid escapes
+ """
+
+ def _unescape(chars: str) -> str:
+ """Try to unescape chars. If that results in a valid Json5 value we keep the unescaped version."""
+ if len(chars) and chars[0] in ("[", "{"):
+ pre = chars[0]
+ chars = chars[1:]
+ else:
+ pre = ""
+ if len(chars) and chars[-1] in ("]", "}", ","):
+ post = chars[-1]
+ chars = chars[:-1]
+ else:
+ post = ""
+
+ unescaped = codecs.decode(chars, "unicode-escape")
+ try:
+ json5.decode("{ key : " + unescaped + "}")
+ except Json5Exception:
+ return pre + chars + post # need to keep the escaping to have valid Json5
+ else: # unescaped this is still valid Json5
+ return pre + unescaped + post
+
+ def _pretty_print(chars: str) -> None: # noqa: C901
+ nonlocal fp, level, indent, _list, _collect
+
+ # first all actions with explicit fp.write
+ if chars == ":":
+ if compact:
+ _c = _collect.strip()
+ no_quote = _c.strip('"').strip("'").strip('"').strip("'")
+ try:
+ json5.decode("{" + no_quote + " : 'dummy'}")
+ except Json5Exception:
+ _collect += ": "
+ else:
+ _collect = f"{no_quote}: "
+ _ = fp.write(_collect)
+ _collect = ""
+ elif chars == "{":
+ level += 1
+ _collect += "{\n" + " " * (level * indent)
+ elif chars == "," and _list == 0:
+ _collect += ",\n" + " " * (level * indent)
+ else: # default
+ _collect += chars
+ # level and _list handling
+ if chars == "}":
+ level -= 1
+ elif chars == "[":
+ _list += 1
+ elif chars == "]":
+ _list -= 1
+ # write to file and reset _collect
+ if chars in {"{", "}", "[", "]", ","}:
+ _ = fp.write(_unescape(_collect))
+ _collect = ""
+
+ assert json5.encode_noop(js5), f"Python object {js5} is not serializable as Json5"
+ if indent == -1: # just dump it no pretty print, Json5 features, ...
+ txt = json5.encode(js5, quotationmark="'")
+ with Path(file).open(mode="w") as fp:
+ _ = fp.write(txt)
+
+ elif indent >= 0: # pretty-print and other features are taken into account
+ level: int = 0
+ _list: int = 0
+ _collect: str = ""
+ with Path(file).open(mode="w") as fp:
+ _ = json5.encode_callback(
+ data=js5,
+ cb=_pretty_print,
+ supply_bytes=False,
+ quotationmark="'",
+ )
+
+
+def json5_find_identifier_start(txt: str, pos: int) -> int:
+ """Find the position of the start of the identifier in txt going backwards from pos."""
+ p: int = pos - 1
+ while True:
+ if p < 0:
+ return 0
+ if txt[p] in (",", "{", "}", "[", "]", ":"):
+ return p + 1
+ p -= 1
+
+
+def json5_try_correct(txt: str, pos: int) -> tuple[bool, str]:
+ """Try to repair the json5 illegal character found at pos in txt.
+
+ 1. Check whether pos points to a key and set the key in quotation marks.
+ 2. Check whether pos points to an illegal comment marker and replace with //
+ """
+ success: bool = False
+ if txt[pos] == "#": # python type comment
+ txt = f"{txt[:pos]}//{txt[pos + 1 :]}"
+ success = True
+ else:
+ m = re.search(":", txt[pos:])
+ if m is None:
+ logger.warning(f"No key found at {txt[pos : pos + 15]}...")
+ else:
+ key = txt[pos : pos + m.start()].strip()
+ m2 = re.search(r"\s|,|\{|\}|\[|\]", key)
+ if m2 is not None:
+ logger.warning(f"The key candidate {key} is not a Json5 key")
+ else:
+ txt = f"{txt[:pos]} '{key}' : {txt[pos + m.end() :]}"
+ success = True
+ return (success, txt)
+
+
+def json5_read( # noqa: C901, PLR0912
+ file: Path | str,
+ *,
+ save: int = 0,
+) -> dict[str, Any]:
+ """Read the Json5 file.
+ If key or comment errors are encountered they are tried fixed 'en route'.
+ save: 0: do not save, 1: save if changed, 2: save in any case. Overwrite file when saving.
+ """
+
+ def get_line(txt: str, pos: int) -> int:
+ """Get the line number related to pos in txt, counting newline.
+ If no more line breaks are found, the current line count is returned.
+ """
+ _p = 0
+ line = 0
+ while True:
+ _p = txt.find("\n", _p) + 1
+ if _p > pos or _p <= 0:
+ return line + 1
+ line += 1
+
+ with Path(file).open(mode="r") as fp:
+ txt = fp.read()
+ num_warn = 0
+ while True:
+ try:
+ js5 = json5.decode(txt, maxdepth=-1)
+ except Json5Exception as err:
+ if err.__class__ is Json5IllegalCharacter:
+ num_warn += 1
+ pos = get_pos(str(err)) - 1
+ _line = get_line(txt, pos)
+ if err.args[0].startswith("Expected b'comma'"):
+ raise ValueError(f"Missing comma? in {file}, line {_line} at {txt[pos : pos + 20]}") from err
+ if err.args[0].startswith("Expected b'IdentifierStart'"):
+ success, txt = json5_try_correct(txt, pos)
+ if not success:
+ raise ValueError(
+ f"{file} Unrepairable identifier in {txt[pos : pos + 15]}, line {_line}"
+ ) from err
+ elif err.args[0].startswith("Expected b'colon'"): # the illegal character is i middle of the key!
+ pos = json5_find_identifier_start(txt, pos)
+ success, txt = json5_try_correct(txt, pos)
+ if not success:
+ raise ValueError(f"{file} Unrepairable key in {txt[pos : pos + 15]}, line {_line}") from err
+
+ else:
+ raise ValueError(f"Unhandled illegal character problem in {file}, line {_line}.") from err
+ else:
+ raise ValueError(f"Unhandled problem in Json5 file {file}: {err.args[0]}") from err
+ else:
+ break
+ if save == 0 and num_warn > 0:
+ logger.warning(f"Decoding the file {file}, {num_warn} illegal characters were detected. Not saved.")
+ elif (save == 1 and num_warn > 0) or save == 2: # noqa: PLR2004
+ logger.warning(f"Decoding the file {file}, {num_warn} illegal characters were detected. File re-saved.")
+ json5_write(js5, file, indent=3, compact=True)
+ return js5
+
+
+def _spath_to_keys(spath: str) -> list[str]:
+ """Extract the keys from path.
+ So far this is a minimum implementation for adding data. Probably this could be done using jsonpath-ng.
+ """
+ keys: list[str] = []
+ spath = spath.lstrip("$.")
+ if spath.startswith("$["):
+ spath = spath[1:]
+ c: re.Pattern[str] = re.compile(r"\[(.*?)\]")
+ while m := c.search(spath):
+ if m.start() > 0:
+ keys.extend(spath[: m.start()].split("."))
+ keys.append(spath[m.start() + 1 : m.end() - 1])
+ spath = spath[m.end() :]
+ if len(spath.strip()):
+ keys.extend(spath.split("."))
+ return keys
+
+
+_VT = TypeVar("_VT", bound=Any)
+
+
+@overload
+def json5_path(
+ js5: dict[str, Any],
+ path: str,
+ typ: type[_VT],
+) -> _VT | None: ...
+
+
+@overload
+def json5_path(
+ js5: dict[str, Any],
+ path: str,
+ typ: None = None,
+) -> Any | None: # noqa: ANN401
+ ...
+
+
+def json5_path(
+ js5: dict[str, Any],
+ path: str,
+ typ: type[_VT] | None = None,
+) -> _VT | Any | None:
+ """Evaluate a JsonPath expression on the Json5 code and return the result.
+
+ Syntax see `RFC9535 `_
+ and `jsonpath-ng (used here) `_
+
+ * $: root node identifier (Section 2.2)
+ * @: current node identifier (Section 2.3.5) (valid only within filter selectors)
+ * []: child segment (Section 2.5.1): selects zero or more children of a node
+ * .name: shorthand for ['name']
+ * .*: shorthand for [*]
+ * ..[]: descendant segment (Section 2.5.2): selects zero or more descendants of a node
+ * ..name: shorthand for ..['name']
+ * ..*: shorthand for ..[*]
+ * 'name': name selector (Section 2.3.1): selects a named child of an object
+ * *: wildcard selector (Section 2.3.2): selects all children of a node
+ * i: (int) index selector (Section 2.3.3): selects an indexed child of an array (from 0)
+ * 0:100:5: array slice selector (Section 2.3.4): start:end:step for arrays
+ * ?: filter selector (Section 2.3.5): selects particular children using a logical expression
+ * length(@.foo): function extension (Section 2.4): invokes a function in a filter expression
+
+ Args:
+ js5 (dict): a Json5 conformant dict
+ path (str): path expression as string.
+ typ (type)=None: optional specification of the expected type to find
+ """
+ try:
+ compiled = parse(path)
+ except JsonPathParserError as e:
+ raise ValueError(f"Invalid JsonPath expression: {path}\n{e}") from e
+ data: list[DatumInContext] = compiled.find(js5)
+ val: Any | list[Any] | None = None
+ if not len(data): # not found
+ logger.info(f"No match for {path}. Returning None.")
+ elif len(data) == 1: # found a single element
+ val = data[0].value
+ else: # found multiple elements
+ val = [x.value for x in data]
+
+ if val is not None and typ is not None and not isinstance(val, typ):
+ try: # try to convert
+ val = typ(val)
+ except Exception as e:
+ raise ValueError(f"{path} matches, but type {typ} does not match {type(val)}.") from e
+ return val
+
+
+@overload
+def json5_update(
+ js5: dict[str, Any],
+ *,
+ spath: str,
+ data: dict[str, Any] | list[Any] | Any, # noqa: ANN401
+) -> None: ...
+
+
+@overload
+def json5_update(
+ js5: dict[str, Any],
+ *,
+ keys: Sequence[str],
+ data: dict[str, Any] | list[Any] | Any, # noqa: ANN401
+) -> None: ...
+
+
+def json5_update(
+ js5: dict[str, Any],
+ *,
+ spath: str | None = None,
+ keys: Sequence[str] | None = None,
+ data: dict[str, Any]
+ | list[Any]
+ | Any
+ | None = None, # 'None' necessary here only for type checking (due to the overloads). At runtime `data` must not be None.
+) -> None:
+ """Append data to the js5 dict at the path pointed to by keys.
+ So far this is a minimum implementation for adding data.
+
+ Args:
+ js5 (dict[str, Any]): A Json5 conformant dict
+ spath (str): A JsonPath expression as string. If provided, the keys are extracted from the spath and used to update the dict. If not provided, the keys argument is used.
+ keys (Sequence[str]): Sequence of keys. All keys down to the place where to update the dict shall be included
+ data (dict[str, Any] | list[Any] | Any): the data to be added/updated. Dicts are updated, lists are appended
+ """
+ if spath is not None:
+ keys = _spath_to_keys(spath)
+ if keys is None:
+ raise ValueError("Either 'spath' or 'keys' must be provided")
+ assert data is not None, "Data to update must be provided"
+ path: dict[str, Any] | list[Any] | Any = js5
+ parent: dict[str, Any] | list[Any] | Any = js5
+ for i, k in enumerate(keys):
+ if k not in path:
+ for j in range(len(keys) - 1, i - 1, -1):
+ data = {keys[j]: data}
+ break
+ # NOTE: `assert` is necessary as `path[k]` will be an invalid get operation if `path` is not a dict.
+ # TODO @EisDNV: Check and possibly improve code to allow accessing also indexed elements in lists.
+ # ClaasRostock, 2025-01-26.
+ assert isinstance(path, dict)
+ parent = path
+ path = path[k]
+ if isinstance(path, list):
+ path.append(data)
+ elif isinstance(path, dict):
+ path.update(data)
+ elif isinstance(parent, dict): # update the parent dict (replace a value)
+ parent.update({k: data})
+ else:
+ raise TypeError(f"Unknown type of path: {path}")
diff --git a/src/sim_explorer/utils/osp.py b/src/sim_explorer/utils/osp.py
index e88b7cf..4b65563 100644
--- a/src/sim_explorer/utils/osp.py
+++ b/src/sim_explorer/utils/osp.py
@@ -5,7 +5,7 @@
from component_model.utils.xml import read_xml
-from sim_explorer.json5 import Json5
+from sim_explorer.utils.json5 import json5_path, json5_read
# ==========================================
@@ -16,7 +16,7 @@ def make_osp_system_structure( # noqa: C901, PLR0913, PLR0915
version: str = "0.1",
start: float = 0.0,
base_step: float = 0.01,
- algorithm: str = "fixedStep", # noqa: ARG001
+ algorithm: str = "fixedStep",
simulators: dict[str, Any] | None = None,
functions_linear: dict[str, Any] | None = None,
functions_sum: dict[str, Any] | None = None,
@@ -79,7 +79,7 @@ def make_simulators(simulators: dict[str, Any] | None) -> ET.Element:
def make_initial_value(
var: str,
- val: int | float | bool | str,
+ val: int | float | bool | str, # noqa: FBT001
) -> ET.Element:
"""Make a element from the provided var dict."""
typ: str = {int: "Integer", float: "Real", bool: "Boolean", str: "String"}[type(val)]
@@ -254,11 +254,12 @@ def make_connection(
)
osp.append(element_text(tag="StartTime", text=str(start)))
osp.append(element_text(tag="BaseStepSize", text=str(base_step)))
+ osp.append(element_text(tag="Algorithm", text=algorithm))
osp.append(make_simulators(simulators))
osp.append(make_functions(functions_linear, functions_sum, functions_vectorsum))
osp.append(make_connections(connections_variable, connections_signal, connections_group, connections_signalgroup))
tree = ET.ElementTree(osp)
- ET.indent(tree, space=" ", level=0)
+ ET.indent(tree, space=" ", level=0)
file: Path = Path(path).absolute() / f"{name}.xml"
tree.write(file, encoding="utf-8")
return file
@@ -270,22 +271,22 @@ def osp_system_structure_from_js5(file: Path, dest: Path | None = None) -> Path:
"""
assert file.exists(), f"File {file} not found"
assert file.name.endswith(".js5"), f"Json5 file expected. Found {file.name}"
- js = Json5(file)
+ js = json5_read(file)
ss = make_osp_system_structure(
name=file.name[:-4],
- version=js.jspath("$.header.version", str) or "0.1",
- start=js.jspath("$.header.StartTime", float) or 0.0,
- base_step=js.jspath("$.header.BaseStepSize", float) or 0.01,
- algorithm=js.jspath("$.header.algorithm", str) or "fixedStep",
- simulators=js.jspath("$.Simulators", dict) or {},
- functions_linear=js.jspath("$.FunctionsLinear", dict) or {},
- functions_sum=js.jspath("$.FunctionsSum", dict) or {},
- functions_vectorsum=js.jspath("$.FunctionsVectorSum", dict) or {},
- connections_variable=js.jspath(path="$.ConnectionsVariable", typ=list),
- connections_signal=js.jspath(path="$.ConnectionsSignal", typ=list),
- connections_group=js.jspath(path="$.ConnectionsGroup", typ=list),
- connections_signalgroup=js.jspath(path="$.ConnectionsSignalGroup", typ=list),
+ version=json5_path(js, "$.header.version", str) or "0.1",
+ start=json5_path(js, "$.header.StartTime", float) or 0.0,
+ base_step=json5_path(js, "$.header.BaseStepSize", float) or 0.01,
+ algorithm=json5_path(js, "$.header.algorithm", str) or "fixedStep",
+ simulators=json5_path(js, "$.Simulators", dict) or {},
+ functions_linear=json5_path(js, "$.FunctionsLinear", dict) or {},
+ functions_sum=json5_path(js, "$.FunctionsSum", dict) or {},
+ functions_vectorsum=json5_path(js, "$.FunctionsVectorSum", dict) or {},
+ connections_variable=json5_path(js, "$.ConnectionsVariable", list),
+ connections_signal=json5_path(js, "$.ConnectionsSignal", list),
+ connections_group=json5_path(js, "$.ConnectionsGroup", list),
+ connections_signalgroup=json5_path(js, "$.ConnectionsSignalGroup", list),
path=dest or Path(file).parent,
)
@@ -332,9 +333,9 @@ def type_value(el: ET.Element) -> int | float | bool | str:
for con in el.findall(".//{*}" + c + "Connection"):
assert len(con) == 2, f"Two sub-elements expected. Found {len(con)}" # noqa: PLR2004
cons.append([p for i in range(2) for p in con[i].attrib.values()])
- if len(cons):
+ if cons:
connections[f"Connections{c}"] = cons
- if len(connections):
+ if connections:
structure.update(connections)
return structure
diff --git a/src/sim_explorer/utils/paths.py b/src/sim_explorer/utils/paths.py
index 06bb7e3..d693943 100644
--- a/src/sim_explorer/utils/paths.py
+++ b/src/sim_explorer/utils/paths.py
@@ -15,11 +15,18 @@ def relative_path(p1: Path, p2: Path) -> str:
def get_path(p1: str, base: Path | None = None) -> Path:
- """Get the full path of p1, which could be relative to base."""
+ """Get the full path of p1.
+
+ 1. if p1 exists and no base provided or the full path is provided and exists, p1 is returned as Path object
+ 2. if base is provided, p1 relative to base is returned
+ 3. if base is not provided (None), p1 relative to the current directory (cwd) is returned.
+
+ This is useful for specification files, where absolute paths cannot be used.
+ """
+ if Path(p1).exists() and (p1 == str(Path(p1).resolve()) or base is None):
+ return Path(p1).resolve()
if base is None:
base = Path.cwd()
- if Path(p1).exists():
- return Path(p1).resolve()
p = (base / Path(p1)).resolve()
if p.exists():
return p
diff --git a/tests/cli/test_sim_explorer_cli.py b/tests/cli/test_sim_explorer_cli.py
index 479fa06..9ed3f7e 100644
--- a/tests/cli/test_sim_explorer_cli.py
+++ b/tests/cli/test_sim_explorer_cli.py
@@ -1,3 +1,4 @@
+# pyright: reportPrivateUsage=false
import sys
from argparse import ArgumentError
from dataclasses import dataclass, field
@@ -6,7 +7,7 @@
import pytest
from sim_explorer.cli import __main__
-from sim_explorer.cli.__main__ import _argparser, main # pyright: ignore[reportPrivateUsage]
+from sim_explorer.cli.__main__ import _argparser, main
# *****Test commandline interface (CLI)************************************************************
@@ -78,10 +79,7 @@ class ConfigureLoggingArgs:
([], ArgumentError),
(["test_config_file"], ConfigureLoggingArgs()),
(["test_config_file", "-q"], ConfigureLoggingArgs(log_level_console="ERROR")),
- (
- ["test_config_file", "--quiet"],
- ConfigureLoggingArgs(log_level_console="ERROR"),
- ),
+ (["test_config_file", "--quiet"], ConfigureLoggingArgs(log_level_console="ERROR")),
(["test_config_file", "-v"], ConfigureLoggingArgs(log_level_console="INFO")),
(
["test_config_file", "--verbose"],
diff --git a/tests/conftest.py b/tests/conftest.py
index 74e85b2..6b338a3 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,3 +1,5 @@
+"""Test configuration and fixtures."""
+
import logging
import os
from pathlib import Path
@@ -6,20 +8,20 @@
import pytest
-@pytest.fixture(scope="package", autouse=True)
+@pytest.fixture(scope="session", autouse=True)
def chdir() -> None:
"""
Fixture that changes the current working directory to the 'test_working_directory' folder.
- This fixture is automatically used for the entire package.
+ This fixture is automatically used for the entire session.
"""
os.chdir(Path(__file__).parent.absolute() / "test_working_directory")
-@pytest.fixture(scope="package", autouse=True)
+@pytest.fixture(scope="session", autouse=True)
def test_dir() -> Path:
"""
Fixture that returns the absolute path of the directory containing the current file.
- This fixture is automatically used for the entire package.
+ This fixture is automatically used for the entire session.
"""
return Path(__file__).parent.absolute()
@@ -29,7 +31,12 @@ def test_dir() -> Path:
]
output_files = [
"*test*.pdf",
- "systemModel.xml",
+ "*.xml",
+ "*.log",
+ "*.js5",
+ "*.cases",
+ "test_results",
+ "*.fmu",
]
@@ -53,7 +60,8 @@ def _remove_output_dirs_and_files() -> None:
for pattern in output_files:
for file in Path.cwd().glob(pattern):
_file = Path(file)
- _file.unlink(missing_ok=True)
+ if _file.is_file():
+ _file.unlink(missing_ok=True)
@pytest.fixture(autouse=True)
@@ -73,9 +81,14 @@ def logger() -> logging.Logger:
def pytest_addoption(parser: pytest.Parser) -> None:
- parser.addoption("--show", action="store", default=False)
+ parser.addoption(
+ "--show",
+ action="store_true",
+ default=False,
+ help="Command line switch to show plots during tests, and dump additional results to console. By default, False.",
+ )
@pytest.fixture(scope="session")
def show(request: pytest.FixtureRequest) -> bool:
- return request.config.getoption("--show") == "True"
+ return request.config.getoption("--show")
diff --git a/tests/data/BouncingBall0/BouncingBall.cases b/tests/data/BouncingBall0/BouncingBall.cases
index 7eba2f6..f24f233 100644
--- a/tests/data/BouncingBall0/BouncingBall.cases
+++ b/tests/data/BouncingBall0/BouncingBall.cases
@@ -1,45 +1,39 @@
{
-header: {
- name : 'BouncingBall',
- description : 'Simple sim explorer with the basic BouncingBall FMU (ball dropped from h=1m',
- modelFile : "OspSystemStructure.xml",
- simulator : "OSP"
- logLevel : 'fatal', # possible levels: trace, debug, info, warning, error, fatal
- timeUnit : "second",
- variables : {
- g : ['bb', 'g', "Gravity acting on the ball"],
- e : ['bb', 'e', "Coefficient of restitution"],
- v_min : ['bb', 'v_min', "Velocity below which the ball stops bouncing"],
- h : ['bb', 'h', "Position (z) of the ball"],
- v_z : ['bb', 'der(h)', "Derivative of h (speed in z-direction"],
- v : ['bb', 'v', "Velocity of ball"],
- a_z : ['bb', 'der(v)', "Derivative of v (acceleration in z-direction)"],
- }},
-base : {
- description : "Variable settings for the base case. All other cases are based on that",
- spec: {
- stepSize : 0.01,
- stopTime : 3.0,
- g : -9.81,
- e : 1.0,
- h : 1.0,
- h@step : 'result',
- v@1.0 : 'result',
- }},
-restitution : {
- description : "Smaller coefficient of restitution e",
- spec: {
- e : 0.5,
- }},
-restitutionAndGravity : {
- description : "Based restitution (e change), change also the gravity g",
- parent : 'restitution',
- spec : {
- g : -1.5
- }},
-gravity : {
- description : "Gravity like on the moon",
- spec : {
- g : -1.5
- }},
-}
+ header: {
+ name: 'BouncingBall',
+ description: 'Simple sim explorer with the basic BouncingBall FMU (ball dropped from h=1m',
+ modelFile: 'OspSystemStructure.xml',
+ simulator: 'OSP',
+ logLevel: 'fatal',
+ timeUnit: 'second',
+ variables: {
+ g: ['bb','g','Gravity acting on the ball'],
+ e: ['bb','e','Coefficient of restitution'],
+ v_min: ['bb','v_min','Velocity below which the ball stops bouncing'],
+ h: ['bb','h','Position (z) of the ball'],
+ v_z: ['bb','der(h)','Derivative of h (speed in z-direction'],
+ v: ['bb','v','Velocity of ball'],
+ a_z: ['bb','der(v)','Derivative of v (acceleration in z-direction)']}},
+ base: {
+ description: 'Variable settings for the base case. All other cases are based on that',
+ spec: {
+ stepSize: 0.01,
+ stopTime: 3.0,
+ g: -9.81,
+ e: 1.0,
+ h: 1.0,
+ 'h@step': 'result',
+ 'v@1.0': 'result'}},
+ restitution: {
+ description: 'Smaller coefficient of restitution e',
+ spec: {
+ e: 0.5}},
+ restitutionAndGravity: {
+ description: 'Based restitution (e change), change also the gravity g',
+ parent: 'restitution',
+ spec: {
+ g: -1.5}},
+ gravity: {
+ description: 'Gravity like on the moon',
+ spec: {
+ g: -1.5}}}
\ No newline at end of file
diff --git a/tests/data/BouncingBall0/OspSystemStructure.xml b/tests/data/BouncingBall0/OspSystemStructure.xml
index e235771..de94624 100644
--- a/tests/data/BouncingBall0/OspSystemStructure.xml
+++ b/tests/data/BouncingBall0/OspSystemStructure.xml
@@ -1,7 +1,7 @@
-
+
0.01
+ fixedStep
@@ -12,4 +12,4 @@
-
\ No newline at end of file
+
diff --git a/tests/data/BouncingBall3D/BouncingBall3D.cases b/tests/data/BouncingBall3D/BouncingBall3D.cases
index fd8cf51..f4ff10b 100644
--- a/tests/data/BouncingBall3D/BouncingBall3D.cases
+++ b/tests/data/BouncingBall3D/BouncingBall3D.cases
@@ -1,53 +1,61 @@
-{header : {
- name : 'BouncingBall3D',
- description : 'Simple sim explorer with the 3D BouncingBall FMU (3D position and speed',
- modelFile : "OspSystemStructure.xml",
- simulator : "OSP"
- logLevel : 'fatal', # possible levels: trace, debug, info, warning, error, fatal
- timeUnit : "second",
- variables : {
- g : ['bb', 'g', "Gravity acting on the ball"],
- e : ['bb', 'e', "Coefficient of restitution"],
- x : ['bb', 'pos', "3D Position of the ball in meters"],
- v : ['bb', 'speed', "3D speed of ball in meters/second"],
- x_b : ['bb', 'p_bounce', "Expected 3D Position where the next bounce will occur (in meters)"],
- }},
-base : {
- description : "Ball dropping from height 1 m. Results should be the same as the basic BouncingBall",
- spec: {
- stepSize : 0.01,
- stopTime : 3,
- g : 9.81,
- e : 1.0,
- x[2] : 39.37007874015748, # this is in inch => 1m!
- x@step : 'result',
- v@step : 'result',
- x_b@step : 'res',
- }},
-restitution : {
- description : "Smaller coefficient of restitution e",
- spec: {
- e : 0.5,
- }},
-restitutionAndGravity : {
- description : "Based restitution (e change), change also the gravity g",
- parent : 'restitution',
- spec : {
- g : 1.5
- },
- assert: {
- 1@A : ['g==1.5', 'Check setting of gravity (about 1/7 of earth)'],
- 2@ALWAYS : ['e==0.5', 'Check setting of restitution'],
- 3@F : ['x[2] < 3.0', 'For long times the z-position of the ball remains small (loss of energy)'],
- 4@T1.1547 : ['abs(x[2]) < 0.4', 'Close to bouncing time the ball should be close to the floor'],
- }
-},
-gravity : {
- description : "Gravity like on the moon",
- spec : {
- g : 1.5
- },
- assert: {
- 6@ALWAYS: ['g==9.81', 'Check wrong gravity.']
- }
-}}
+{
+ header: {
+ name: 'BouncingBall3D',
+ description: 'Simple sim explorer with the 3D BouncingBall FMU (3D position and speed)',
+ modelFile: 'OspSystemStructure.xml',
+ simulator: 'OSP',
+ logLevel: 'fatal',
+ timeUnit: 'second',
+ variables: {
+ g: ['bb','g','Gravity acting on the ball'],
+ e: ['bb','e','Coefficient of restitution'],
+ x: ['bb','pos','3D Position of the ball in meters'],
+ v: ['bb','speed','3D speed of ball in meters/second'],
+ x_b: ['bb','p_bounce','Expected 3D Position where the next bounce will occur (in meters)'],
+ },
+ },
+ base: {
+ description: 'Ball dropping from height 1 m. Results should be the same as the basic BouncingBall',
+ spec: {
+ stepSize: 0.01,
+ stopTime: 3,
+ g: 9.81,
+ e: 1.0,
+ 'x[2]': 39.37007874015748,
+ 'x@step': 'result',
+ 'v@step': 'result',
+ 'x_b@step': 'res',
+ },
+ },
+ restitution: {
+ description: 'Smaller coefficient of restitution e',
+ spec: {
+ e: 0.5,
+ },
+ },
+ restitutionAndGravity: {
+ description: 'Based restitution (e change), change also the gravity g',
+ parent: 'restitution',
+ spec: {
+ g: 1.5,
+ },
+ assert: {
+ '1@A': ['g==1.5','Check setting of gravity (about 1/7 of earth)'],
+ '2@ALWAYS': ['e==0.5','Check setting of restitution'],
+ '3@F': ['x[2] < 3.0','For long times the z-position of the ball remains small (loss of energy)'],
+ '4@T1.1547': ['abs(x[2]) < 0.4','Close to bouncing time the ball should be close to the floor'],
+ },
+ },
+ gravity: {
+ description: 'Gravity like on the moon',
+ spec: {
+ g: 1.5,
+ },
+ assert: {
+ '6@ALWAYS': [
+ 'g==9.81',
+ 'Check wrong gravity.',
+ ],
+ },
+ },
+}
diff --git a/tests/data/BouncingBall3D/BouncingBall3D.fmu b/tests/data/BouncingBall3D/BouncingBall3D.fmu
index d2565d9..5326c90 100644
Binary files a/tests/data/BouncingBall3D/BouncingBall3D.fmu and b/tests/data/BouncingBall3D/BouncingBall3D.fmu differ
diff --git a/tests/data/BouncingBall3D/OspSystemStructure.xml b/tests/data/BouncingBall3D/OspSystemStructure.xml
index 1a6645a..924cba7 100644
--- a/tests/data/BouncingBall3D/OspSystemStructure.xml
+++ b/tests/data/BouncingBall3D/OspSystemStructure.xml
@@ -1,11 +1,11 @@
-
+
+ 0.0
0.01
+ fixedStep
-
-
+
-
-
-
\ No newline at end of file
+
+
+
diff --git a/tests/data/BouncingBall3D/crane_table.xml b/tests/data/BouncingBall3D/crane_table.xml
index e15cd3b..dbecee8 100644
--- a/tests/data/BouncingBall3D/crane_table.xml
+++ b/tests/data/BouncingBall3D/crane_table.xml
@@ -1,15 +1,17 @@
+
- 0.0
- 0.01
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+ 0.0
+ 0.01
+ fixedStep
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/data/BouncingBall3D/systemModel.xml b/tests/data/BouncingBall3D/systemModel.xml
index e15cd3b..dbecee8 100644
--- a/tests/data/BouncingBall3D/systemModel.xml
+++ b/tests/data/BouncingBall3D/systemModel.xml
@@ -1,15 +1,17 @@
+
- 0.0
- 0.01
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+ 0.0
+ 0.01
+ fixedStep
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/data/BouncingBall3D/test_case b/tests/data/BouncingBall3D/test_case
index c078bb6..3429761 100644
--- a/tests/data/BouncingBall3D/test_case
+++ b/tests/data/BouncingBall3D/test_case
@@ -1,2412 +1,5727 @@
{
-header : {
- case : 'restitutionAndGravity',
- dateTime : '2024-10-31T12:17:00.240916',
- cases : 'BouncingBall3D',
- file : 'BouncingBall3D.cases',
- casesDate : '2024-10-31T12:00:16.724092',
- logLevel : 'FATAL'
- timeUnit : 'second',
- timeFactor : 1000000000.0},
-
-0.01 : {
- bb : {
- e : 0.5,
- g : 1.5,
- x : [0.01,0.0,39.36712598425197],
-
- v : [1.0,0.0,-0.015],
-
- x_b[0] : 1.1547005383792517}},
-
-0.02 : {
- bb : {
- x : [0.02,0.0,39.35826771653543],
-
- v : [1.0,0.0,-0.03],
-
- x_b[0] : 1.1547005383792517}},
-
-0.03 : {
- bb : {
- x : [0.03,0.0,39.343503937007874],
-
- v : [1.0,0.0,-0.045],
-
- x_b[0] : 1.1547005383792517}},
-
-0.04 : {
- bb : {
- x : [0.04,0.0,39.32283464566929],
-
- v : [1.0,0.0,-0.06],
-
- x_b[0] : 1.1547005383792517}},
-
-0.05 : {
- bb : {
- x : [0.05,0.0,39.29625984251968],
-
- v : [1.0,0.0,-0.075],
-
- x_b[0] : 1.1547005383792517}},
-
-0.06 : {
- bb : {
- x : [0.06,0.0,39.26377952755906],
-
- v : [1.0,0.0,-0.09],
-
- x_b[0] : 1.1547005383792517}},
-
-0.07 : {
- bb : {
- x : [0.07,0.0,39.22539370078741],
-
- v : [1.0,0.0,-0.10500000000000001],
-
- x_b[0] : 1.1547005383792517}},
-
-0.08 : {
- bb : {
- x : [0.08,0.0,39.181102362204726],
-
- v : [1.0,0.0,-0.12],
-
- x_b[0] : 1.1547005383792517}},
-
-0.09 : {
- bb : {
- x : [0.09,0.0,39.13090551181102],
-
- v : [1.0,0.0,-0.13499999999999998],
-
- x_b[0] : 1.1547005383792517}},
-
-0.1 : {
- bb : {
- x : [0.1,0.0,39.074803149606296],
-
- v : [1.0,0.0,-0.15],
-
- x_b[0] : 1.1547005383792517}},
-
-0.11 : {
- bb : {
- x : [0.11,0.0,39.01279527559055],
-
- v : [1.0,0.0,-0.16499999999999998],
-
- x_b[0] : 1.1547005383792517}},
-
-0.12 : {
- bb : {
- x : [0.12,0.0,38.94488188976378],
-
- v : [1.0,0.0,-0.17999999999999997],
-
- x_b[0] : 1.1547005383792517}},
-
-0.13 : {
- bb : {
- x : [0.13,0.0,38.871062992125985],
-
- v : [1.0,0.0,-0.19499999999999998],
-
- x_b[0] : 1.1547005383792517}},
-
-0.14 : {
- bb : {
- x : [0.14,0.0,38.79133858267716],
-
- v : [1.0,0.0,-0.21],
-
- x_b[0] : 1.1547005383792517}},
-
-0.15 : {
- bb : {
- x : [0.15,0.0,38.705708661417326],
-
- v : [1.0,0.0,-0.22499999999999998],
-
- x_b[0] : 1.1547005383792517}},
-
-0.16 : {
- bb : {
- x : [0.16,0.0,38.61417322834645],
-
- v : [1.0,0.0,-0.24],
-
- x_b[0] : 1.1547005383792517}},
-
-0.17 : {
- bb : {
- x : [0.17,0.0,38.51673228346456],
-
- v : [1.0,0.0,-0.255],
-
- x_b[0] : 1.1547005383792517}},
-
-0.18 : {
- bb : {
- x : [0.18,0.0,38.41338582677165],
-
- v : [1.0,0.0,-0.26999999999999996],
-
- x_b[0] : 1.1547005383792517}},
-
-0.19 : {
- bb : {
- x : [0.19,0.0,38.30413385826772],
-
- v : [1.0,0.0,-0.285],
-
- x_b[0] : 1.1547005383792517}},
-
-0.2 : {
- bb : {
- x : [0.2,0.0,38.188976377952756],
-
- v : [1.0,0.0,-0.3],
-
- x_b[0] : 1.1547005383792517}},
-
-0.21 : {
- bb : {
- x : [0.21,0.0,38.06791338582678],
-
- v : [1.0,0.0,-0.31499999999999995],
-
- x_b[0] : 1.1547005383792517}},
-
-0.22 : {
- bb : {
- x : [0.22,0.0,37.94094488188977],
-
- v : [1.0,0.0,-0.32999999999999996],
-
- x_b[0] : 1.1547005383792517}},
-
-0.23 : {
- bb : {
- x : [0.23,0.0,37.80807086614173],
-
- v : [1.0,0.0,-0.345],
-
- x_b[0] : 1.1547005383792517}},
-
-0.24 : {
- bb : {
- x : [0.24,0.0,37.66929133858268],
-
- v : [1.0,0.0,-0.35999999999999993],
-
- x_b[0] : 1.1547005383792517}},
-
-0.25 : {
- bb : {
- x : [0.25,0.0,37.5246062992126],
-
- v : [1.0,0.0,-0.37499999999999994],
-
- x_b[0] : 1.1547005383792517}},
-
-0.26 : {
- bb : {
- x : [0.26,0.0,37.3740157480315],
-
- v : [1.0,0.0,-0.38999999999999996],
-
- x_b[0] : 1.1547005383792517}},
-
-0.27 : {
- bb : {
- x : [0.27,0.0,37.21751968503938],
-
- v : [1.0,0.0,-0.40499999999999997],
-
- x_b[0] : 1.1547005383792517}},
-
-0.28 : {
- bb : {
- x : [0.28,0.0,37.05511811023622],
-
- v : [1.0,0.0,-0.42],
-
- x_b[0] : 1.1547005383792517}},
-
-0.29 : {
- bb : {
- x : [0.29,0.0,36.88681102362205],
-
- v : [1.0,0.0,-0.43499999999999994],
-
- x_b[0] : 1.1547005383792517}},
-
-0.3 : {
- bb : {
- x : [0.3,0.0,36.71259842519685],
-
- v : [1.0,0.0,-0.44999999999999996],
-
- x_b[0] : 1.1547005383792517}},
-
-0.31 : {
- bb : {
- x : [0.31,0.0,36.53248031496063],
-
- v : [1.0,0.0,-0.46499999999999997],
-
- x_b[0] : 1.1547005383792517}},
-
-0.32 : {
- bb : {
- x : [0.32,0.0,36.34645669291339],
-
- v : [1.0,0.0,-0.48],
-
- x_b[0] : 1.1547005383792517}},
-
-0.33 : {
- bb : {
- x : [0.33,0.0,36.154527559055126],
-
- v : [1.0,0.0,-0.495],
-
- x_b[0] : 1.1547005383792517}},
-
-0.34 : {
- bb : {
- x : [0.34,0.0,35.95669291338583],
-
- v : [1.0,0.0,-0.51],
-
- x_b[0] : 1.1547005383792517}},
-
-0.35 : {
- bb : {
- x : [0.35,0.0,35.75295275590552],
-
- v : [1.0,0.0,-0.5249999999999999],
-
- x_b[0] : 1.1547005383792517}},
-
-0.36 : {
- bb : {
- x : [0.36,0.0,35.54330708661418],
-
- v : [1.0,0.0,-0.5399999999999999],
-
- x_b[0] : 1.1547005383792517}},
-
-0.37 : {
- bb : {
- x : [0.37,0.0,35.327755905511815],
-
- v : [1.0,0.0,-0.5549999999999999],
-
- x_b[0] : 1.1547005383792517}},
-
-0.38 : {
- bb : {
- x : [0.38,0.0,35.10629921259843],
-
- v : [1.0,0.0,-0.57],
-
- x_b[0] : 1.1547005383792517}},
-
-0.39 : {
- bb : {
- x : [0.39,0.0,34.87893700787402],
-
- v : [1.0,0.0,-0.585],
-
- x_b[0] : 1.1547005383792517}},
-
-0.4 : {
- bb : {
- x : [0.4,0.0,34.64566929133859],
-
- v : [1.0,0.0,-0.6],
-
- x_b[0] : 1.1547005383792517}},
-
-0.41 : {
- bb : {
- x : [0.41,0.0,34.40649606299213],
-
- v : [1.0,0.0,-0.6149999999999999],
-
- x_b[0] : 1.1547005383792517}},
-
-0.42 : {
- bb : {
- x : [0.42,0.0,34.16141732283465],
-
- v : [1.0,0.0,-0.6299999999999999],
-
- x_b[0] : 1.1547005383792517}},
-
-0.43 : {
- bb : {
- x : [0.43,0.0,33.91043307086615],
-
- v : [1.0,0.0,-0.6449999999999999],
-
- x_b[0] : 1.1547005383792517}},
-
-0.44 : {
- bb : {
- x : [0.44,0.0,33.65354330708662],
-
- v : [1.0,0.0,-0.6599999999999999],
-
- x_b[0] : 1.1547005383792517}},
-
-0.45 : {
- bb : {
- x : [0.45,0.0,33.390748031496074],
-
- v : [1.0,0.0,-0.6749999999999999],
-
- x_b[0] : 1.1547005383792517}},
-
-0.46 : {
- bb : {
- x : [0.46,0.0,33.122047244094496],
-
- v : [1.0,0.0,-0.69],
-
- x_b[0] : 1.1547005383792517}},
-
-0.47 : {
- bb : {
- x : [0.47,0.0,32.8474409448819],
-
- v : [1.0,0.0,-0.7049999999999998],
-
- x_b[0] : 1.1547005383792517}},
-
-0.48 : {
- bb : {
- x : [0.48,0.0,32.56692913385828],
-
- v : [1.0,0.0,-0.7199999999999999],
-
- x_b[0] : 1.1547005383792517}},
-
-0.49 : {
- bb : {
- x : [0.49,0.0,32.28051181102363],
-
- v : [1.0,0.0,-0.7349999999999999],
-
- x_b[0] : 1.1547005383792517}},
-
-0.5 : {
- bb : {
- x : [0.5,0.0,31.988188976377963],
-
- v : [1.0,0.0,-0.7499999999999999],
-
- x_b[0] : 1.1547005383792517}},
-
-0.51 : {
- bb : {
- x : [0.51,0.0,31.68996062992127],
-
- v : [1.0,0.0,-0.7649999999999999],
-
- x_b[0] : 1.1547005383792517}},
-
-0.52 : {
- bb : {
- x : [0.52,0.0,31.38582677165355],
-
- v : [1.0,0.0,-0.7799999999999999],
-
- x_b[0] : 1.1547005383792517}},
-
-0.53 : {
- bb : {
- x : [0.53,0.0,31.075787401574814],
-
- v : [1.0,0.0,-0.7949999999999999],
-
- x_b[0] : 1.1547005383792517}},
-
-0.54 : {
- bb : {
- x : [0.54,0.0,30.759842519685048],
-
- v : [1.0,0.0,-0.8099999999999999],
-
- x_b[0] : 1.1547005383792517}},
-
-0.55 : {
- bb : {
- x : [0.55,0.0,30.43799212598426],
-
- v : [1.0,0.0,-0.825],
-
- x_b[0] : 1.1547005383792517}},
-
-0.56 : {
- bb : {
- x : [0.56,0.0,30.110236220472448],
-
- v : [1.0,0.0,-0.84],
-
- x_b[0] : 1.1547005383792517}},
-
-0.57 : {
- bb : {
- x : [0.57,0.0,29.776574803149614],
-
- v : [1.0,0.0,-0.8549999999999998],
-
- x_b[0] : 1.1547005383792517}},
-
-0.58 : {
- bb : {
- x : [0.58,0.0,29.43700787401576],
-
- v : [1.0,0.0,-0.8699999999999998],
-
- x_b[0] : 1.1547005383792517}},
-
-0.59 : {
- bb : {
- x : [0.59,0.0,29.091535433070877],
-
- v : [1.0,0.0,-0.8849999999999998],
-
- x_b[0] : 1.1547005383792517}},
-
-0.6 : {
- bb : {
- x : [0.6,0.0,28.740157480314974],
-
- v : [1.0,0.0,-0.8999999999999998],
-
- x_b[0] : 1.1547005383792517}},
-
-0.61 : {
- bb : {
- x : [0.61,0.0,28.38287401574804],
-
- v : [1.0,0.0,-0.9149999999999998],
-
- x_b[0] : 1.1547005383792517}},
-
-0.62 : {
- bb : {
- x : [0.62,0.0,28.01968503937009],
-
- v : [1.0,0.0,-0.9299999999999998],
-
- x_b[0] : 1.1547005383792517}},
-
-0.63 : {
- bb : {
- x : [0.63,0.0,27.65059055118111],
-
- v : [1.0,0.0,-0.9449999999999998],
-
- x_b[0] : 1.1547005383792517}},
-
-0.64 : {
- bb : {
- x : [0.64,0.0,27.27559055118111],
-
- v : [1.0,0.0,-0.9599999999999999],
-
- x_b[0] : 1.1547005383792517}},
-
-0.65 : {
- bb : {
- x : [0.65,0.0,26.89468503937009],
-
- v : [1.0,0.0,-0.9749999999999999],
-
- x_b[0] : 1.1547005383792517}},
-
-0.66 : {
- bb : {
- x : [0.66,0.0,26.50787401574804],
-
- v : [1.0,0.0,-0.9899999999999999],
-
- x_b[0] : 1.1547005383792517}},
-
-0.67 : {
- bb : {
- x : [0.67,0.0,26.115157480314974],
-
- v : [1.0,0.0,-1.005],
-
- x_b[0] : 1.1547005383792517}},
-
-0.68 : {
- bb : {
- x : [0.68,0.0,25.716535433070874],
-
- v : [1.0,0.0,-1.02],
-
- x_b[0] : 1.1547005383792517}},
-
-0.69 : {
- bb : {
- x : [0.69,0.0,25.31200787401576],
-
- v : [1.0,0.0,-1.035],
-
- x_b[0] : 1.1547005383792517}},
-
-0.7 : {
- bb : {
- x : [0.7,0.0,24.901574803149618],
-
- v : [1.0,0.0,-1.0499999999999998],
-
- x_b[0] : 1.1547005383792517}},
-
-0.71 : {
- bb : {
- x : [0.71,0.0,24.48523622047245],
-
- v : [1.0,0.0,-1.065],
-
- x_b[0] : 1.1547005383792517}},
-
-0.72 : {
- bb : {
- x : [0.72,0.0,24.062992125984266],
-
- v : [1.0,0.0,-1.08],
-
- x_b[0] : 1.1547005383792517}},
-
-0.73 : {
- bb : {
- x : [0.73,0.0,23.634842519685055],
-
- v : [1.0,0.0,-1.0950000000000002],
-
- x_b[0] : 1.1547005383792517}},
-
-0.74 : {
- bb : {
- x : [0.74,0.0,23.200787401574814],
-
- v : [1.0,0.0,-1.1100000000000003],
-
- x_b[0] : 1.1547005383792517}},
-
-0.75 : {
- bb : {
- x : [0.75,0.0,22.76082677165355],
-
- v : [1.0,0.0,-1.1250000000000004],
-
- x_b[0] : 1.1547005383792517}},
-
-0.76 : {
- bb : {
- x : [0.76,0.0,22.31496062992127],
-
- v : [1.0,0.0,-1.1400000000000006],
-
- x_b[0] : 1.1547005383792517}},
-
-0.77 : {
- bb : {
- x : [0.77,0.0,21.863188976377963],
-
- v : [1.0,0.0,-1.1550000000000007],
-
- x_b[0] : 1.1547005383792517}},
-
-0.78 : {
- bb : {
- x : [0.78,0.0,21.40551181102363],
-
- v : [1.0,0.0,-1.1700000000000008],
-
- x_b[0] : 1.1547005383792517}},
-
-0.79 : {
- bb : {
- x : [0.79,0.0,20.941929133858277],
-
- v : [1.0,0.0,-1.185000000000001],
-
- x_b[0] : 1.1547005383792517}},
-
-0.8 : {
- bb : {
- x : [0.8,0.0,20.472440944881896],
-
- v : [1.0,0.0,-1.200000000000001],
-
- x_b[0] : 1.1547005383792517}},
-
-0.81 : {
- bb : {
- x : [0.81,0.0,19.997047244094492],
-
- v : [1.0,0.0,-1.2150000000000012],
-
- x_b[0] : 1.1547005383792517}},
-
-0.82 : {
- bb : {
- x : [0.82,0.0,19.515748031496074],
-
- v : [1.0,0.0,-1.230000000000001],
-
- x_b[0] : 1.1547005383792517}},
-
-0.83 : {
- bb : {
- x : [0.83,0.0,19.028543307086622],
-
- v : [1.0,0.0,-1.245000000000001],
-
- x_b[0] : 1.1547005383792517}},
-
-0.84 : {
- bb : {
- x : [0.84,0.0,18.53543307086615],
-
- v : [1.0,0.0,-1.2600000000000011],
-
- x_b[0] : 1.1547005383792517}},
-
-0.85 : {
- bb : {
- x : [0.85,0.0,18.03641732283465],
-
- v : [1.0,0.0,-1.2750000000000012],
-
- x_b[0] : 1.1547005383792517}},
-
-0.86 : {
- bb : {
- x : [0.86,0.0,17.53149606299213],
-
- v : [1.0,0.0,-1.2900000000000014],
-
- x_b[0] : 1.1547005383792517}},
-
-0.87 : {
- bb : {
- x : [0.87,0.0,17.02066929133859],
-
- v : [1.0,0.0,-1.3050000000000015],
-
- x_b[0] : 1.1547005383792517}},
-
-0.88 : {
- bb : {
- x : [0.88,0.0,16.50393700787402],
-
- v : [1.0,0.0,-1.3200000000000016],
-
- x_b[0] : 1.1547005383792517}},
-
-0.89 : {
- bb : {
- x : [0.89,0.0,15.981299212598426],
-
- v : [1.0,0.0,-1.3350000000000017],
-
- x_b[0] : 1.1547005383792517}},
-
-0.9 : {
- bb : {
- x : [0.9,0.0,15.452755905511811],
-
- v : [1.0,0.0,-1.3500000000000019],
-
- x_b[0] : 1.1547005383792517}},
-
-0.91 : {
- bb : {
- x : [0.91,0.0,14.918307086614174],
-
- v : [1.0,0.0,-1.365000000000002],
-
- x_b[0] : 1.1547005383792517}},
-
-0.92 : {
- bb : {
- x : [0.92,0.0,14.377952755905511],
-
- v : [1.0,0.0,-1.3800000000000021],
-
- x_b[0] : 1.1547005383792517}},
-
-0.93 : {
- bb : {
- x : [0.93,0.0,13.831692913385824],
-
- v : [1.0,0.0,-1.3950000000000022],
-
- x_b[0] : 1.1547005383792517}},
-
-0.94 : {
- bb : {
- x : [0.94,0.0,13.27952755905512],
-
- v : [1.0,0.0,-1.4100000000000021],
-
- x_b[0] : 1.1547005383792517}},
-
-0.95 : {
- bb : {
- x : [0.95,0.0,12.721456692913385],
-
- v : [1.0,0.0,-1.425000000000002],
-
- x_b[0] : 1.1547005383792517}},
-
-0.96 : {
- bb : {
- x : [0.96,0.0,12.15748031496063],
-
- v : [1.0,0.0,-1.4400000000000022],
-
- x_b[0] : 1.1547005383792517}},
-
-0.97 : {
- bb : {
- x : [0.97,0.0,11.587598425196848],
-
- v : [1.0,0.0,-1.4550000000000023],
-
- x_b[0] : 1.1547005383792517}},
-
-0.98 : {
- bb : {
- x : [0.98,0.0,11.011811023622043],
-
- v : [1.0,0.0,-1.4700000000000024],
-
- x_b[0] : 1.1547005383792517}},
-
-0.99 : {
- bb : {
- x : [0.99,0.0,10.430118110236215],
-
- v : [1.0,0.0,-1.4850000000000025],
-
- x_b[0] : 1.1547005383792517}},
-
-1.0 : {
- bb : {
- x : [1.0,0.0,9.842519685039363],
-
- v : [1.0,0.0,-1.5000000000000027],
-
- x_b[0] : 1.1547005383792517}},
-
-1.01 : {
- bb : {
- x : [1.01,0.0,9.249015748031487],
-
- v : [1.0,0.0,-1.5150000000000028],
-
- x_b[0] : 1.1547005383792517}},
-
-1.02 : {
- bb : {
- x : [1.02,0.0,8.64960629921259],
-
- v : [1.0,0.0,-1.530000000000003],
-
- x_b[0] : 1.1547005383792517}},
-
-1.03 : {
- bb : {
- x : [1.03,0.0,8.044291338582665],
-
- v : [1.0,0.0,-1.545000000000003],
-
- x_b[0] : 1.1547005383792517}},
-
-1.04 : {
- bb : {
- x : [1.04,0.0,7.433070866141719],
-
- v : [1.0,0.0,-1.5600000000000032],
-
- x_b[0] : 1.1547005383792517}},
-
-1.05 : {
- bb : {
- x : [1.05,0.0,6.815944881889749],
-
- v : [1.0,0.0,-1.5750000000000033],
-
- x_b[0] : 1.1547005383792517}},
-
-1.06 : {
- bb : {
- x : [1.06,0.0,6.192913385826755],
-
- v : [1.0,0.0,-1.5900000000000034],
-
- x_b[0] : 1.1547005383792517}},
-
-1.07 : {
- bb : {
- x : [1.07,0.0,5.563976377952738],
-
- v : [1.0,0.0,-1.6050000000000035],
-
- x_b[0] : 1.1547005383792517}},
-
-1.08 : {
- bb : {
- x : [1.08,0.0,4.929133858267696],
-
- v : [1.0,0.0,-1.6200000000000037],
-
- x_b[0] : 1.1547005383792517}},
-
-1.09 : {
- bb : {
- x : [1.09,0.0,4.2883858267716315],
-
- v : [1.0,0.0,-1.6350000000000038],
-
- x_b[0] : 1.1547005383792517}},
-
-1.1 : {
- bb : {
- x : [1.1,0.0,3.6417322834645427],
-
- v : [1.0,0.0,-1.650000000000004],
-
- x_b[0] : 1.1547005383792517}},
-
-1.11 : {
- bb : {
- x : [1.11,0.0,2.9891732283464307],
-
- v : [1.0,0.0,-1.665000000000004],
-
- x_b[0] : 1.1547005383792517}},
-
-1.12 : {
- bb : {
- x : [1.12,0.0,2.330708661417295],
-
- v : [1.0,0.0,-1.6800000000000042],
-
- x_b[0] : 1.1547005383792517}},
-
-1.13 : {
- bb : {
- x : [1.13,0.0,1.6663385826771504],
-
- v : [1.0,0.0,-1.6950000000000038],
-
- x_b[0] : 1.1547005383792517}},
-
-1.14 : {
- bb : {
- x : [1.14,0.0,0.9960629921259674],
-
- v : [1.0,0.0,-1.710000000000004],
-
- x_b[0] : 1.1547005383792517}},
-
-1.15 : {
- bb : {
- x : [1.15,0.0,0.31988188976376064],
-
- v : [1.0,0.0,-1.725000000000004],
-
- x_b[0] : 1.1547005383792517}},
-
-1.16 : {
- bb : {
- x : [1.1573502691896258,0.0,0.17985847125379134],
-
- v : [0.5,0.0,0.8580762113533185],
-
- x_b[0] : 1.732050807568879}},
-
-1.17 : {
- bb : {
- x : [1.1623502691896257,0.0,0.5147309954086413],
-
- v : [0.5,0.0,0.8430762113533184],
-
- x_b[0] : 1.732050807568879}},
-
-1.18 : {
- bb : {
- x : [1.1673502691896256,0.0,0.8436980077524677],
-
- v : [0.5,0.0,0.8280762113533184],
-
- x_b[0] : 1.732050807568879}},
-
-1.19 : {
- bb : {
- x : [1.1723502691896255,0.0,1.1667595082852704],
-
- v : [0.5,0.0,0.8130762113533184],
-
- x_b[0] : 1.732050807568879}},
-
-1.2 : {
- bb : {
- x : [1.1773502691896254,0.0,1.4839154970070494],
-
- v : [0.5,0.0,0.7980762113533184],
-
- x_b[0] : 1.732050807568879}},
-
-1.21 : {
- bb : {
- x : [1.1823502691896253,0.0,1.7951659739178052],
-
- v : [0.5,0.0,0.7830762113533184],
-
- x_b[0] : 1.732050807568879}},
-
-1.22 : {
- bb : {
- x : [1.1873502691896252,0.0,2.100510939017537],
-
- v : [0.5,0.0,0.7680762113533184],
-
- x_b[0] : 1.732050807568879}},
-
-1.23 : {
- bb : {
- x : [1.192350269189625,0.0,2.3999503923062453],
-
- v : [0.5,0.0,0.7530762113533184],
-
- x_b[0] : 1.732050807568879}},
-
-1.24 : {
- bb : {
- x : [1.197350269189625,0.0,2.6934843337839296],
-
- v : [0.5,0.0,0.7380762113533184],
-
- x_b[0] : 1.732050807568879}},
-
-1.25 : {
- bb : {
- x : [1.2023502691896248,0.0,2.9811127634505907],
-
- v : [0.5,0.0,0.7230762113533183],
-
- x_b[0] : 1.732050807568879}},
-
-1.26 : {
- bb : {
- x : [1.2073502691896247,0.0,3.2628356813062283],
-
- v : [0.5,0.0,0.7080762113533183],
-
- x_b[0] : 1.732050807568879}},
-
-1.27 : {
- bb : {
- x : [1.2123502691896246,0.0,3.538653087350842],
-
- v : [0.5,0.0,0.6930762113533183],
-
- x_b[0] : 1.732050807568879}},
-
-1.28 : {
- bb : {
- x : [1.2173502691896245,0.0,3.808564981584432],
-
- v : [0.5,0.0,0.6780762113533183],
-
- x_b[0] : 1.732050807568879}},
-
-1.29 : {
- bb : {
- x : [1.2223502691896244,0.0,4.072571364006999],
-
- v : [0.5,0.0,0.6630762113533183],
-
- x_b[0] : 1.732050807568879}},
-
-1.3 : {
- bb : {
- x : [1.2273502691896243,0.0,4.330672234618541],
-
- v : [0.5,0.0,0.6480762113533183],
-
- x_b[0] : 1.732050807568879}},
-
-1.31 : {
- bb : {
- x : [1.2323502691896242,0.0,4.582867593419061],
-
- v : [0.5,0.0,0.6330762113533183],
-
- x_b[0] : 1.732050807568879}},
-
-1.32 : {
- bb : {
- x : [1.237350269189624,0.0,4.829157440408556],
-
- v : [0.5,0.0,0.6180762113533183],
-
- x_b[0] : 1.732050807568879}},
-
-1.33 : {
- bb : {
- x : [1.242350269189624,0.0,5.0695417755870285],
-
- v : [0.5,0.0,0.6030762113533182],
-
- x_b[0] : 1.732050807568879}},
-
-1.34 : {
- bb : {
- x : [1.2473502691896239,0.0,5.304020598954477],
-
- v : [0.5,0.0,0.5880762113533182],
-
- x_b[0] : 1.732050807568879}},
-
-1.35 : {
- bb : {
- x : [1.2523502691896238,0.0,5.532593910510901],
-
- v : [0.5,0.0,0.5730762113533182],
-
- x_b[0] : 1.732050807568879}},
-
-1.36 : {
- bb : {
- x : [1.2573502691896237,0.0,5.755261710256303],
-
- v : [0.5,0.0,0.5580762113533182],
-
- x_b[0] : 1.732050807568879}},
-
-1.37 : {
- bb : {
- x : [1.2623502691896236,0.0,5.9720239981906795],
-
- v : [0.5,0.0,0.5430762113533182],
-
- x_b[0] : 1.732050807568879}},
-
-1.38 : {
- bb : {
- x : [1.2673502691896235,0.0,6.182880774314028],
-
- v : [0.5,0.0,0.5280762113533185],
-
- x_b[0] : 1.732050807568879}},
-
-1.39 : {
- bb : {
- x : [1.2723502691896234,0.0,6.3878320386263585],
-
- v : [0.5,0.0,0.5130762113533185],
-
- x_b[0] : 1.732050807568879}},
-
-1.4 : {
- bb : {
- x : [1.2773502691896232,0.0,6.586877791127665],
-
- v : [0.5,0.0,0.4980762113533185],
-
- x_b[0] : 1.732050807568879}},
-
-1.41 : {
- bb : {
- x : [1.2823502691896231,0.0,6.780018031817948],
-
- v : [0.5,0.0,0.48307621135331846],
-
- x_b[0] : 1.732050807568879}},
-
-1.42 : {
- bb : {
- x : [1.287350269189623,0.0,6.967252760697208],
-
- v : [0.5,0.0,0.46807621135331845],
-
- x_b[0] : 1.732050807568879}},
-
-1.43 : {
- bb : {
- x : [1.292350269189623,0.0,7.148581977765444],
-
- v : [0.5,0.0,0.45307621135331844],
-
- x_b[0] : 1.732050807568879}},
-
-1.44 : {
- bb : {
- x : [1.2973502691896228,0.0,7.324005683022656],
-
- v : [0.5,0.0,0.4380762113533184],
-
- x_b[0] : 1.732050807568879}},
-
-1.45 : {
- bb : {
- x : [1.3023502691896227,0.0,7.493523876468845],
-
- v : [0.5,0.0,0.4230762113533184],
-
- x_b[0] : 1.732050807568879}},
-
-1.46 : {
- bb : {
- x : [1.3073502691896226,0.0,7.65713655810401],
-
- v : [0.5,0.0,0.4080762113533184],
-
- x_b[0] : 1.732050807568879}},
-
-1.47 : {
- bb : {
- x : [1.3123502691896225,0.0,7.81484372792815],
-
- v : [0.5,0.0,0.3930762113533184],
-
- x_b[0] : 1.732050807568879}},
-
-1.48 : {
- bb : {
- x : [1.3173502691896224,0.0,7.966645385941268],
-
- v : [0.5,0.0,0.37807621135331837],
-
- x_b[0] : 1.732050807568879}},
-
-1.49 : {
- bb : {
- x : [1.3223502691896223,0.0,8.112541532143362],
-
- v : [0.5,0.0,0.36307621135331836],
-
- x_b[0] : 1.732050807568879}},
-
-1.5 : {
- bb : {
- x : [1.3273502691896222,0.0,8.252532166534433],
-
- v : [0.5,0.0,0.34807621135331834],
-
- x_b[0] : 1.732050807568879}},
-
-1.51 : {
- bb : {
- x : [1.332350269189622,0.0,8.38661728911448],
-
- v : [0.5,0.0,0.33307621135331833],
-
- x_b[0] : 1.732050807568879}},
-
-1.52 : {
- bb : {
- x : [1.337350269189622,0.0,8.514796899883503],
-
- v : [0.5,0.0,0.3180762113533183],
-
- x_b[0] : 1.732050807568879}},
-
-1.53 : {
- bb : {
- x : [1.3423502691896219,0.0,8.637070998841502],
-
- v : [0.5,0.0,0.3030762113533183],
-
- x_b[0] : 1.732050807568879}},
-
-1.54 : {
- bb : {
- x : [1.3473502691896218,0.0,8.753439585988477],
-
- v : [0.5,0.0,0.2880762113533183],
-
- x_b[0] : 1.732050807568879}},
-
-1.55 : {
- bb : {
- x : [1.3523502691896216,0.0,8.86390266132443],
-
- v : [0.5,0.0,0.2730762113533183],
-
- x_b[0] : 1.732050807568879}},
-
-1.56 : {
- bb : {
- x : [1.3573502691896215,0.0,8.968460224849359],
-
- v : [0.5,0.0,0.25807621135331826],
-
- x_b[0] : 1.732050807568879}},
-
-1.57 : {
- bb : {
- x : [1.3623502691896214,0.0,9.067112276563263],
-
- v : [0.5,0.0,0.24307621135331825],
-
- x_b[0] : 1.732050807568879}},
-
-1.58 : {
- bb : {
- x : [1.3673502691896213,0.0,9.159858816466144],
-
- v : [0.5,0.0,0.22807621135331824],
-
- x_b[0] : 1.732050807568879}},
-
-1.59 : {
- bb : {
- x : [1.3723502691896212,0.0,9.246699844558002],
-
- v : [0.5,0.0,0.21307621135331822],
-
- x_b[0] : 1.732050807568879}},
-
-1.6 : {
- bb : {
- x : [1.3773502691896211,0.0,9.327635360838835],
-
- v : [0.5,0.0,0.1980762113533182],
-
- x_b[0] : 1.732050807568879}},
-
-1.61 : {
- bb : {
- x : [1.382350269189621,0.0,9.402665365308646],
-
- v : [0.5,0.0,0.1830762113533182],
-
- x_b[0] : 1.732050807568879}},
-
-1.62 : {
- bb : {
- x : [1.387350269189621,0.0,9.471789857967433],
-
- v : [0.5,0.0,0.16807621135331818],
-
- x_b[0] : 1.732050807568879}},
-
-1.63 : {
- bb : {
- x : [1.3923502691896208,0.0,9.535008838815195],
-
- v : [0.5,0.0,0.1530762113533185],
-
- x_b[0] : 1.732050807568879}},
-
-1.64 : {
- bb : {
- x : [1.3973502691896207,0.0,9.592322307851934],
-
- v : [0.5,0.0,0.1380762113533185],
-
- x_b[0] : 1.732050807568879}},
-
-1.65 : {
- bb : {
- x : [1.4023502691896206,0.0,9.64373026507765],
-
- v : [0.5,0.0,0.12307621135331848],
-
- x_b[0] : 1.732050807568879}},
-
-1.66 : {
- bb : {
- x : [1.4073502691896205,0.0,9.689232710492343],
-
- v : [0.5,0.0,0.10807621135331846],
-
- x_b[0] : 1.732050807568879}},
-
-1.67 : {
- bb : {
- x : [1.4123502691896204,0.0,9.728829644096011],
-
- v : [0.5,0.0,0.09307621135331845],
-
- x_b[0] : 1.732050807568879}},
-
-1.68 : {
- bb : {
- x : [1.4173502691896203,0.0,9.762521065888656],
-
- v : [0.5,0.0,0.07807621135331844],
-
- x_b[0] : 1.732050807568879}},
-
-1.69 : {
- bb : {
- x : [1.4223502691896202,0.0,9.790306975870278],
-
- v : [0.5,0.0,0.06307621135331842],
-
- x_b[0] : 1.732050807568879}},
-
-1.7 : {
- bb : {
- x : [1.42735026918962,0.0,9.812187374040876],
-
- v : [0.5,0.0,0.04807621135331841],
-
- x_b[0] : 1.732050807568879}},
-
-1.71 : {
- bb : {
- x : [1.43235026918962,0.0,9.82816226040045],
-
- v : [0.5,0.0,0.0330762113533184],
-
- x_b[0] : 1.732050807568879}},
-
-1.72 : {
- bb : {
- x : [1.4373502691896198,0.0,9.838231634949],
-
- v : [0.5,0.0,0.018076211353318383],
-
- x_b[0] : 1.732050807568879}},
-
-1.73 : {
- bb : {
- x : [1.4423502691896197,0.0,9.842395497686528],
-
- v : [0.5,0.0,0.00307621135331837],
-
- x_b[0] : 1.732050807568879}},
-
-1.74 : {
- bb : {
- x : [1.4473502691896196,0.0,9.84065384861303],
-
- v : [0.5,0.0,-0.011923788646681643],
-
- x_b[0] : 1.732050807568879}},
-
-1.75 : {
- bb : {
- x : [1.4523502691896195,0.0,9.83300668772851],
-
- v : [0.5,0.0,-0.026923788646681657],
-
- x_b[0] : 1.732050807568879}},
-
-1.76 : {
- bb : {
- x : [1.4573502691896194,0.0,9.819454015032965],
-
- v : [0.5,0.0,-0.04192378864668167],
-
- x_b[0] : 1.732050807568879}},
-
-1.77 : {
- bb : {
- x : [1.4623502691896193,0.0,9.799995830526399],
-
- v : [0.5,0.0,-0.05692378864668168],
-
- x_b[0] : 1.732050807568879}},
-
-1.78 : {
- bb : {
- x : [1.4673502691896192,0.0,9.774632134208806],
-
- v : [0.5,0.0,-0.0719237886466817],
-
- x_b[0] : 1.732050807568879}},
-
-1.79 : {
- bb : {
- x : [1.472350269189619,0.0,9.743362926080191],
-
- v : [0.5,0.0,-0.08692378864668171],
-
- x_b[0] : 1.732050807568879}},
-
-1.8 : {
- bb : {
- x : [1.477350269189619,0.0,9.706188206140553],
-
- v : [0.5,0.0,-0.10192378864668172],
-
- x_b[0] : 1.732050807568879}},
-
-1.81 : {
- bb : {
- x : [1.4823502691896189,0.0,9.663107974389892],
-
- v : [0.5,0.0,-0.11692378864668174],
-
- x_b[0] : 1.732050807568879}},
-
-1.82 : {
- bb : {
- x : [1.4873502691896188,0.0,9.614122230828205],
-
- v : [0.5,0.0,-0.13192378864668175],
-
- x_b[0] : 1.732050807568879}},
-
-1.83 : {
- bb : {
- x : [1.4923502691896187,0.0,9.559230975455495],
-
- v : [0.5,0.0,-0.14692378864668176],
-
- x_b[0] : 1.732050807568879}},
-
-1.84 : {
- bb : {
- x : [1.4973502691896186,0.0,9.498434208271764],
-
- v : [0.5,0.0,-0.16192378864668178],
-
- x_b[0] : 1.732050807568879}},
-
-1.85 : {
- bb : {
- x : [1.5023502691896184,0.0,9.431731929277007],
-
- v : [0.5,0.0,-0.1769237886466818],
-
- x_b[0] : 1.732050807568879}},
-
-1.86 : {
- bb : {
- x : [1.5073502691896183,0.0,9.359124138471225],
-
- v : [0.5,0.0,-0.1919237886466818],
-
- x_b[0] : 1.732050807568879}},
-
-1.87 : {
- bb : {
- x : [1.5123502691896182,0.0,9.280610835854421],
-
- v : [0.5,0.0,-0.20692378864668182],
-
- x_b[0] : 1.732050807568879}},
-
-1.88 : {
- bb : {
- x : [1.5173502691896181,0.0,9.196192021426596],
-
- v : [0.5,0.0,-0.2219237886466815],
-
- x_b[0] : 1.732050807568879}},
-
-1.89 : {
- bb : {
- x : [1.522350269189618,0.0,9.105867695187744],
-
- v : [0.5,0.0,-0.2369237886466815],
-
- x_b[0] : 1.732050807568879}},
-
-1.9 : {
- bb : {
- x : [1.527350269189618,0.0,9.00963785713787],
-
- v : [0.5,0.0,-0.2519237886466815],
-
- x_b[0] : 1.732050807568879}},
-
-1.91 : {
- bb : {
- x : [1.5323502691896178,0.0,8.907502507276972],
-
- v : [0.5,0.0,-0.26692378864668154],
-
- x_b[0] : 1.732050807568879}},
-
-1.92 : {
- bb : {
- x : [1.5373502691896177,0.0,8.79946164560505],
-
- v : [0.5,0.0,-0.28192378864668155],
-
- x_b[0] : 1.732050807568879}},
-
-1.93 : {
- bb : {
- x : [1.5423502691896176,0.0,8.685515272122105],
-
- v : [0.5,0.0,-0.29692378864668156],
-
- x_b[0] : 1.732050807568879}},
-
-1.94 : {
- bb : {
- x : [1.5473502691896175,0.0,8.565663386828135],
-
- v : [0.5,0.0,-0.3119237886466816],
-
- x_b[0] : 1.732050807568879}},
-
-1.95 : {
- bb : {
- x : [1.5523502691896174,0.0,8.439905989723142],
-
- v : [0.5,0.0,-0.3269237886466816],
-
- x_b[0] : 1.732050807568879}},
-
-1.96 : {
- bb : {
- x : [1.5573502691896173,0.0,8.308243080807125],
-
- v : [0.5,0.0,-0.3419237886466816],
-
- x_b[0] : 1.732050807568879}},
-
-1.97 : {
- bb : {
- x : [1.5623502691896172,0.0,8.170674660080087],
-
- v : [0.5,0.0,-0.3569237886466816],
-
- x_b[0] : 1.732050807568879}},
-
-1.98 : {
- bb : {
- x : [1.567350269189617,0.0,8.027200727542022],
-
- v : [0.5,0.0,-0.37192378864668163],
-
- x_b[0] : 1.732050807568879}},
-
-1.99 : {
- bb : {
- x : [1.572350269189617,0.0,7.877821283192935],
-
- v : [0.5,0.0,-0.38692378864668164],
-
- x_b[0] : 1.732050807568879}},
-
-2.0 : {
- bb : {
- x : [1.5773502691896168,0.0,7.722536327032824],
-
- v : [0.5,0.0,-0.40192378864668166],
-
- x_b[0] : 1.732050807568879}},
-
-2.01 : {
- bb : {
- x : [1.5823502691896167,0.0,7.561345859061692],
-
- v : [0.5,0.0,-0.41692378864668134],
-
- x_b[0] : 1.732050807568879}},
-
-2.02 : {
- bb : {
- x : [1.5873502691896169,0.0,7.39424987927953],
-
- v : [0.5,0.0,-0.4319237886466817],
-
- x_b[0] : 1.732050807568879}},
-
-2.03 : {
- bb : {
- x : [1.5923502691896168,0.0,7.2212483876863525],
-
- v : [0.5,0.0,-0.44692378864668136],
-
- x_b[0] : 1.732050807568879}},
-
-2.04 : {
- bb : {
- x : [1.5973502691896169,0.0,7.0423413842821425],
-
- v : [0.5,0.0,-0.4619237886466817],
-
- x_b[0] : 1.732050807568879}},
-
-2.05 : {
- bb : {
- x : [1.6023502691896168,0.0,6.8575288690669165],
-
- v : [0.5,0.0,-0.4769237886466814],
-
- x_b[0] : 1.732050807568879}},
-
-2.06 : {
- bb : {
- x : [1.6073502691896169,0.0,6.666810842040659],
-
- v : [0.5,0.0,-0.49192378864668174],
-
- x_b[0] : 1.732050807568879}},
-
-2.07 : {
- bb : {
- x : [1.6123502691896168,0.0,6.470187303203388],
-
- v : [0.5,0.0,-0.5069237886466814],
-
- x_b[0] : 1.732050807568879}},
-
-2.08 : {
- bb : {
- x : [1.6173502691896169,0.0,6.2676582525550835],
-
- v : [0.5,0.0,-0.5219237886466818],
-
- x_b[0] : 1.732050807568879}},
-
-2.09 : {
- bb : {
- x : [1.6223502691896168,0.0,6.059223690095764],
-
- v : [0.5,0.0,-0.5369237886466814],
-
- x_b[0] : 1.732050807568879}},
-
-2.1 : {
- bb : {
- x : [1.627350269189617,0.0,5.844883615825412],
-
- v : [0.5,0.0,-0.5519237886466818],
-
- x_b[0] : 1.732050807568879}},
-
-2.11 : {
- bb : {
- x : [1.6323502691896168,0.0,5.6246380297440455],
-
- v : [0.5,0.0,-0.5669237886466815],
-
- x_b[0] : 1.732050807568879}},
-
-2.12 : {
- bb : {
- x : [1.637350269189617,0.0,5.398486931851647],
-
- v : [0.5,0.0,-0.5819237886466818],
-
- x_b[0] : 1.732050807568879}},
-
-2.13 : {
- bb : {
- x : [1.6423502691896168,0.0,5.166430322148233],
-
- v : [0.5,0.0,-0.5969237886466815],
-
- x_b[0] : 1.732050807568879}},
-
-2.14 : {
- bb : {
- x : [1.647350269189617,0.0,4.928468200633786],
-
- v : [0.5,0.0,-0.6119237886466818],
-
- x_b[0] : 1.732050807568879}},
-
-2.15 : {
- bb : {
- x : [1.6523502691896168,0.0,4.684600567308325],
-
- v : [0.5,0.0,-0.6269237886466815],
-
- x_b[0] : 1.732050807568879}},
-
-2.16 : {
- bb : {
- x : [1.657350269189617,0.0,4.434827422171831],
-
- v : [0.5,0.0,-0.6419237886466819],
-
- x_b[0] : 1.732050807568879}},
-
-2.17 : {
- bb : {
- x : [1.6623502691896168,0.0,4.179148765224324],
-
- v : [0.5,0.0,-0.6569237886466816],
-
- x_b[0] : 1.732050807568879}},
-
-2.18 : {
- bb : {
- x : [1.667350269189617,0.0,3.917564596465782],
-
- v : [0.5,0.0,-0.6719237886466819],
-
- x_b[0] : 1.732050807568879}},
-
-2.19 : {
- bb : {
- x : [1.6723502691896168,0.0,3.6500749158962282],
-
- v : [0.5,0.0,-0.6869237886466816],
-
- x_b[0] : 1.732050807568879}},
-
-2.2 : {
- bb : {
- x : [1.677350269189617,0.0,3.3766797235156387],
-
- v : [0.5,0.0,-0.7019237886466819],
-
- x_b[0] : 1.732050807568879}},
-
-2.21 : {
- bb : {
- x : [1.6823502691896168,0.0,3.0973790193240376],
-
- v : [0.5,0.0,-0.7169237886466816],
-
- x_b[0] : 1.732050807568879}},
-
-2.22 : {
- bb : {
- x : [1.687350269189617,0.0,2.8121728033214004],
-
- v : [0.5,0.0,-0.731923788646682],
-
- x_b[0] : 1.732050807568879}},
-
-2.23 : {
- bb : {
- x : [1.6923502691896168,0.0,2.5210610755077525],
-
- v : [0.5,0.0,-0.7469237886466816],
-
- x_b[0] : 1.732050807568879}},
-
-2.24 : {
- bb : {
- x : [1.697350269189617,0.0,2.2240438358830676],
-
- v : [0.5,0.0,-0.761923788646682],
-
- x_b[0] : 1.732050807568879}},
-
-2.25 : {
- bb : {
- x : [1.7023502691896168,0.0,1.9211210844473727],
-
- v : [0.5,0.0,-0.7769237886466817],
-
- x_b[0] : 1.732050807568879}},
-
-2.26 : {
- bb : {
- x : [1.7073502691896167,0.0,1.6122928212006544],
-
- v : [0.5,0.0,-0.7919237886466813],
-
- x_b[0] : 1.732050807568879}},
-
-2.27 : {
- bb : {
- x : [1.7123502691896169,0.0,1.2975590461428985],
-
- v : [0.5,0.0,-0.8069237886466817],
-
- x_b[0] : 1.732050807568879}},
-
-2.28 : {
- bb : {
- x : [1.7173502691896168,0.0,0.9769197592741332],
-
- v : [0.5,0.0,-0.8219237886466814],
-
- x_b[0] : 1.732050807568879}},
-
-2.29 : {
- bb : {
- x : [1.7223502691896169,0.0,0.6503749605943299],
-
- v : [0.5,0.0,-0.8369237886466817],
-
- x_b[0] : 1.732050807568879}},
-
-2.3 : {
- bb : {
- x : [1.7273502691896168,0.0,0.31792465010351745],
-
- v : [0.5,0.0,-0.8519237886466814],
-
- x_b[0] : 1.732050807568879}},
-
-2.31 : {
- bb : {
- x : [1.7322005383792525,0.0,0.010199698395215402],
-
- v : [0.25,0.0,0.4321143170299793],
-
- x_b[0] : 1.8763883748662857}},
-
-2.32 : {
- bb : {
- x : [1.7347005383792524,0.0,0.17737068935189665],
-
- v : [0.25,0.0,0.41711431702997964],
-
- x_b[0] : 1.8763883748662857}},
-
-2.33 : {
- bb : {
- x : [1.7372005383792524,0.0,0.3386361684975615],
-
- v : [0.25,0.0,0.4021143170299793],
-
- x_b[0] : 1.8763883748662857}},
-
-2.34 : {
- bb : {
- x : [1.7397005383792523,0.0,0.4939961358321958],
-
- v : [0.25,0.0,0.3871143170299796],
-
- x_b[0] : 1.8763883748662857}},
-
-2.35 : {
- bb : {
- x : [1.7422005383792523,0.0,0.6434505913558131],
-
- v : [0.25,0.0,0.37211431702997927],
-
- x_b[0] : 1.8763883748662857}},
-
-2.36 : {
- bb : {
- x : [1.7447005383792522,0.0,0.7869995350684004],
-
- v : [0.25,0.0,0.3571143170299796],
-
- x_b[0] : 1.8763883748662857}},
-
-2.37 : {
- bb : {
- x : [1.7472005383792522,0.0,0.9246429669699702],
-
- v : [0.25,0.0,0.34211431702997924],
-
- x_b[0] : 1.8763883748662857}},
-
-2.38 : {
- bb : {
- x : [1.749700538379252,0.0,1.0563808870605105],
-
- v : [0.25,0.0,0.32711431702997956],
-
- x_b[0] : 1.8763883748662857}},
-
-2.39 : {
- bb : {
- x : [1.752200538379252,0.0,1.1822132953400326],
-
- v : [0.25,0.0,0.3121143170299792],
-
- x_b[0] : 1.8763883748662857}},
-
-2.4 : {
- bb : {
- x : [1.754700538379252,0.0,1.3021401918085258],
-
- v : [0.25,0.0,0.29711431702997954],
-
- x_b[0] : 1.8763883748662857}},
-
-2.41 : {
- bb : {
- x : [1.757200538379252,0.0,1.4161615764660007],
-
- v : [0.25,0.0,0.2821143170299792],
-
- x_b[0] : 1.8763883748662857}},
-
-2.42 : {
- bb : {
- x : [1.7597005383792519,0.0,1.524277449312447],
-
- v : [0.25,0.0,0.2671143170299795],
-
- x_b[0] : 1.8763883748662857}},
-
-2.43 : {
- bb : {
- x : [1.7622005383792518,0.0,1.6264878103478742],
-
- v : [0.25,0.0,0.25211431702997916],
-
- x_b[0] : 1.8763883748662857}},
-
-2.44 : {
- bb : {
- x : [1.7647005383792518,0.0,1.7227926595722731],
-
- v : [0.25,0.0,0.23711431702997948],
-
- x_b[0] : 1.8763883748662857}},
-
-2.45 : {
- bb : {
- x : [1.7672005383792517,0.0,1.813191996985653],
-
- v : [0.25,0.0,0.22211431702997914],
-
- x_b[0] : 1.8763883748662857}},
-
-2.46 : {
- bb : {
- x : [1.7697005383792517,0.0,1.8976858225880051],
-
- v : [0.25,0.0,0.20711431702997946],
-
- x_b[0] : 1.8763883748662857}},
-
-2.47 : {
- bb : {
- x : [1.7722005383792516,0.0,1.9762741363793372],
-
- v : [0.25,0.0,0.1921143170299791],
-
- x_b[0] : 1.8763883748662857}},
-
-2.48 : {
- bb : {
- x : [1.7747005383792516,0.0,2.0489569383596424],
-
- v : [0.25,0.0,0.17711431702997943],
-
- x_b[0] : 1.8763883748662857}},
-
-2.49 : {
- bb : {
- x : [1.7772005383792515,0.0,2.1157342285289276],
-
- v : [0.25,0.0,0.16211431702997908],
-
- x_b[0] : 1.8763883748662857}},
-
-2.5 : {
- bb : {
- x : [1.7797005383792515,0.0,2.1766060068871855],
-
- v : [0.25,0.0,0.1471143170299794],
-
- x_b[0] : 1.8763883748662857}},
-
-2.51 : {
- bb : {
- x : [1.7822005383792514,0.0,2.2315722734344203],
-
- v : [0.25,0.0,0.13211431702997972],
-
- x_b[0] : 1.8763883748662857}},
-
-2.52 : {
- bb : {
- x : [1.7847005383792514,0.0,2.2806330281706337],
-
- v : [0.25,0.0,0.11711431702997938],
-
- x_b[0] : 1.8763883748662857}},
-
-2.53 : {
- bb : {
- x : [1.7872005383792513,0.0,2.3237882710958218],
-
- v : [0.25,0.0,0.1021143170299797],
-
- x_b[0] : 1.8763883748662857}},
-
-2.54 : {
- bb : {
- x : [1.7897005383792512,0.0,2.361038002209988],
-
- v : [0.25,0.0,0.08711431702997935],
-
- x_b[0] : 1.8763883748662857}},
-
-2.55 : {
- bb : {
- x : [1.7922005383792512,0.0,2.3923822215131287],
-
- v : [0.25,0.0,0.07211431702997967],
-
- x_b[0] : 1.8763883748662857}},
-
-2.56 : {
- bb : {
- x : [1.7947005383792511,0.0,2.4178209290052473],
-
- v : [0.25,0.0,0.05711431702997932],
-
- x_b[0] : 1.8763883748662857}},
-
-2.57 : {
- bb : {
- x : [1.797200538379251,0.0,2.4373541246863413],
-
- v : [0.25,0.0,0.04211431702997964],
-
- x_b[0] : 1.8763883748662857}},
-
-2.58 : {
- bb : {
- x : [1.799700538379251,0.0,2.450981808556412],
-
- v : [0.25,0.0,0.027114317029979296],
-
- x_b[0] : 1.8763883748662857}},
-
-2.59 : {
- bb : {
- x : [1.802200538379251,0.0,2.4587039806154594],
-
- v : [0.25,0.0,0.012114317029979615],
-
- x_b[0] : 1.8763883748662857}},
-
-2.6 : {
- bb : {
- x : [1.804700538379251,0.0,2.4605206408634825],
-
- v : [0.25,0.0,-0.002885682970020731],
-
- x_b[0] : 1.8763883748662857}},
-
-2.61 : {
- bb : {
- x : [1.8072005383792509,0.0,2.4564317893004826],
-
- v : [0.25,0.0,-0.01788568297002041],
-
- x_b[0] : 1.8763883748662857}},
-
-2.62 : {
- bb : {
- x : [1.8097005383792508,0.0,2.446437425926458],
-
- v : [0.25,0.0,-0.03288568297002076],
-
- x_b[0] : 1.8763883748662857}},
-
-2.63 : {
- bb : {
- x : [1.8122005383792508,0.0,2.430537550741411],
-
- v : [0.25,0.0,-0.04788568297002044],
-
- x_b[0] : 1.8763883748662857}},
-
-2.64 : {
- bb : {
- x : [1.8147005383792507,0.0,2.4087321637453396],
-
- v : [0.25,0.0,-0.06288568297002078],
-
- x_b[0] : 1.8763883748662857}},
-
-2.65 : {
- bb : {
- x : [1.8172005383792507,0.0,2.381021264938245],
-
- v : [0.25,0.0,-0.07788568297002046],
-
- x_b[0] : 1.8763883748662857}},
-
-2.66 : {
- bb : {
- x : [1.8197005383792506,0.0,2.3474048543201262],
-
- v : [0.25,0.0,-0.09288568297002081],
-
- x_b[0] : 1.8763883748662857}},
-
-2.67 : {
- bb : {
- x : [1.8222005383792506,0.0,2.307882931890985],
-
- v : [0.25,0.0,-0.10788568297002049],
-
- x_b[0] : 1.8763883748662857}},
-
-2.68 : {
- bb : {
- x : [1.8247005383792505,0.0,2.2624554976508184],
-
- v : [0.25,0.0,-0.12288568297002084],
-
- x_b[0] : 1.8763883748662857}},
-
-2.69 : {
- bb : {
- x : [1.8272005383792504,0.0,2.21112255159963],
-
- v : [0.25,0.0,-0.13788568297002052],
-
- x_b[0] : 1.8763883748662857}},
-
-2.7 : {
- bb : {
- x : [1.8297005383792504,0.0,2.1538840937374157],
-
- v : [0.25,0.0,-0.15288568297002086],
-
- x_b[0] : 1.8763883748662857}},
-
-2.71 : {
- bb : {
- x : [1.8322005383792503,0.0,2.090740124064181],
-
- v : [0.25,0.0,-0.16788568297002054],
-
- x_b[0] : 1.8763883748662857}},
-
-2.72 : {
- bb : {
- x : [1.8347005383792503,0.0,2.021690642579919],
-
- v : [0.25,0.0,-0.1828856829700209],
-
- x_b[0] : 1.8763883748662857}},
-
-2.73 : {
- bb : {
- x : [1.8372005383792502,0.0,1.946735649284637],
-
- v : [0.25,0.0,-0.19788568297002057],
-
- x_b[0] : 1.8763883748662857}},
-
-2.74 : {
- bb : {
- x : [1.8397005383792502,0.0,1.865875144178328],
-
- v : [0.25,0.0,-0.21288568297002092],
-
- x_b[0] : 1.8763883748662857}},
-
-2.75 : {
- bb : {
- x : [1.8422005383792501,0.0,1.7791091272609987],
-
- v : [0.25,0.0,-0.2278856829700206],
-
- x_b[0] : 1.8763883748662857}},
-
-2.76 : {
- bb : {
- x : [1.84470053837925,0.0,1.686437598532646],
-
- v : [0.25,0.0,-0.24288568297002028],
-
- x_b[0] : 1.8763883748662857}},
-
-2.77 : {
- bb : {
- x : [1.84720053837925,0.0,1.5878605579932659],
-
- v : [0.25,0.0,-0.2578856829700206],
-
- x_b[0] : 1.8763883748662857}},
-
-2.78 : {
- bb : {
- x : [1.84970053837925,0.0,1.4833780056428665],
-
- v : [0.25,0.0,-0.2728856829700203],
-
- x_b[0] : 1.8763883748662857}},
-
-2.79 : {
- bb : {
- x : [1.85220053837925,0.0,1.3729899414814386],
-
- v : [0.25,0.0,-0.28788568297002065],
-
- x_b[0] : 1.8763883748662857}},
-
-2.8 : {
- bb : {
- x : [1.8547005383792499,0.0,1.2566963655089922],
-
- v : [0.25,0.0,-0.30288568297002033],
-
- x_b[0] : 1.8763883748662857}},
-
-2.81 : {
- bb : {
- x : [1.8572005383792498,0.0,1.134497277725517],
-
- v : [0.25,0.0,-0.3178856829700207],
-
- x_b[0] : 1.8763883748662857}},
-
-2.82 : {
- bb : {
- x : [1.8597005383792498,0.0,1.0063926781310233],
-
- v : [0.25,0.0,-0.33288568297002036],
-
- x_b[0] : 1.8763883748662857}},
-
-2.83 : {
- bb : {
- x : [1.8622005383792497,0.0,0.8723825667255003],
-
- v : [0.25,0.0,-0.3478856829700207],
-
- x_b[0] : 1.8763883748662857}},
-
-2.84 : {
- bb : {
- x : [1.8647005383792497,0.0,0.7324669435089598],
-
- v : [0.25,0.0,-0.3628856829700204],
-
- x_b[0] : 1.8763883748662857}},
-
-2.85 : {
- bb : {
- x : [1.8672005383792496,0.0,0.5866458084813894],
-
- v : [0.25,0.0,-0.37788568297002073],
-
- x_b[0] : 1.8763883748662857}},
-
-2.86 : {
- bb : {
- x : [1.8697005383792495,0.0,0.4349191616428018],
-
- v : [0.25,0.0,-0.3928856829700204],
-
- x_b[0] : 1.8763883748662857}},
-
-2.87 : {
- bb : {
- x : [1.8722005383792495,0.0,0.27728700299318376],
-
- v : [0.25,0.0,-0.40788568297002076],
-
- x_b[0] : 1.8763883748662857}},
-
-2.88 : {
- bb : {
- x : [1.8747005383792494,0.0,0.11374933253254924],
-
- v : [0.25,0.0,-0.42288568297002044],
-
- x_b[0] : 1.8763883748662857}},
-
-2.89 : {
- bb : {
- x : [1.8767944566227692,0.0,0.02737948501553115],
-
- v : [0.125,0.0,0.21163336986830958],
-
- x_b[0] : 1.9124727666906374}},
-
-2.9 : {
- bb : {
- x : [1.8780444566227692,0.0,0.10774695346761987],
-
- v : [0.125,0.0,0.1966333698683099],
-
- x_b[0] : 1.9124727666906374}},
-
-2.91 : {
- bb : {
- x : [1.8792944566227692,0.0,0.1822089101086884],
-
- v : [0.125,0.0,0.18163336986830955],
-
- x_b[0] : 1.9124727666906374}},
-
-2.92 : {
- bb : {
- x : [1.8805444566227691,0.0,0.2507653549387301],
-
- v : [0.125,0.0,0.16663336986830987],
-
- x_b[0] : 1.9124727666906374}},
-
-2.93 : {
- bb : {
- x : [1.8817944566227691,0.0,0.3134162879577511],
-
- v : [0.125,0.0,0.15163336986830953],
-
- x_b[0] : 1.9124727666906374}},
-
-2.94 : {
- bb : {
- x : [1.883044456622769,0.0,0.37016170916574587],
-
- v : [0.125,0.0,0.13663336986830985],
-
- x_b[0] : 1.9124727666906374}},
-
-2.95 : {
- bb : {
- x : [1.884294456622769,0.0,0.42100161856271934],
-
- v : [0.125,0.0,0.1216333698683095],
-
- x_b[0] : 1.9124727666906374}},
-
-2.96 : {
- bb : {
- x : [1.885544456622769,0.0,0.4659360161486671],
-
- v : [0.125,0.0,0.10663336986830982],
-
- x_b[0] : 1.9124727666906374}},
-
-2.97 : {
- bb : {
- x : [1.886794456622769,0.0,0.504964901923593],
-
- v : [0.125,0.0,0.09163336986830947],
-
- x_b[0] : 1.9124727666906374}},
-
-2.98 : {
- bb : {
- x : [1.888044456622769,0.0,0.5380882758874937],
-
- v : [0.125,0.0,0.07663336986830979],
-
- x_b[0] : 1.9124727666906374}},
-
-2.99 : {
- bb : {
- x : [1.889294456622769,0.0,0.5653061380403721],
-
- v : [0.125,0.0,0.061633369868309446],
-
- x_b[0] : 1.9124727666906374}},
-
-3.0 : {
- bb : {
- x : [1.890544456622769,0.0,0.5866184883822259],
-
- v : [0.125,0.0,0.046633369868309765],
-
- x_b[0] : 1.9124727666906374}}}
+ header: {
+ case: 'restitutionAndGravity',
+ dateTime: '2026-03-16T16:39:30.333655+00:00',
+ cases: 'BouncingBall3D',
+ file: './BouncingBall3D.cases',
+ casesDate: '2026-03-12T18:11:35.596000+00:00',
+ timeUnit: 'second',
+ timeFactor: 1000000000.0
+ },
+ '0': {
+ bb: {
+ g: 1.5,
+ e: 0.5,
+ x: [
+ 0.0,
+ 0.0,
+ 39.37007874015748
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.01': {
+ bb: {
+ x: [
+ 0.01,
+ 0.0,
+ 39.36712598425197
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.015
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.02': {
+ bb: {
+ x: [
+ 0.02,
+ 0.0,
+ 39.35826771653543
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.03
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.03': {
+ bb: {
+ x: [
+ 0.03,
+ 0.0,
+ 39.343503937007874
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.045
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.04': {
+ bb: {
+ x: [
+ 0.04,
+ 0.0,
+ 39.32283464566929
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.06
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.05': {
+ bb: {
+ x: [
+ 0.05,
+ 0.0,
+ 39.29625984251968
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.075
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.06': {
+ bb: {
+ x: [
+ 0.06,
+ 0.0,
+ 39.26377952755906
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.09
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.07': {
+ bb: {
+ x: [
+ 0.07,
+ 0.0,
+ 39.22539370078741
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.10500000000000001
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.08': {
+ bb: {
+ x: [
+ 0.08,
+ 0.0,
+ 39.181102362204726
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.12
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.09': {
+ bb: {
+ x: [
+ 0.09,
+ 0.0,
+ 39.13090551181102
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.13499999999999998
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.1': {
+ bb: {
+ x: [
+ 0.1,
+ 0.0,
+ 39.074803149606296
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.15
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.11': {
+ bb: {
+ x: [
+ 0.11,
+ 0.0,
+ 39.01279527559055
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.16499999999999998
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.12': {
+ bb: {
+ x: [
+ 0.12,
+ 0.0,
+ 38.94488188976378
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.17999999999999997
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.13': {
+ bb: {
+ x: [
+ 0.13,
+ 0.0,
+ 38.871062992125985
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.19499999999999998
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.14': {
+ bb: {
+ x: [
+ 0.14,
+ 0.0,
+ 38.79133858267716
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.21
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.15': {
+ bb: {
+ x: [
+ 0.15,
+ 0.0,
+ 38.705708661417326
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.22499999999999998
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.16': {
+ bb: {
+ x: [
+ 0.16,
+ 0.0,
+ 38.61417322834645
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.24
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.17': {
+ bb: {
+ x: [
+ 0.17,
+ 0.0,
+ 38.51673228346456
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.255
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.18': {
+ bb: {
+ x: [
+ 0.18,
+ 0.0,
+ 38.41338582677165
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.26999999999999996
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.19': {
+ bb: {
+ x: [
+ 0.19,
+ 0.0,
+ 38.30413385826772
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.285
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.2': {
+ bb: {
+ x: [
+ 0.2,
+ 0.0,
+ 38.188976377952756
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.3
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.21': {
+ bb: {
+ x: [
+ 0.21,
+ 0.0,
+ 38.06791338582678
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.31499999999999995
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.22': {
+ bb: {
+ x: [
+ 0.22,
+ 0.0,
+ 37.94094488188977
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.32999999999999996
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.23': {
+ bb: {
+ x: [
+ 0.23,
+ 0.0,
+ 37.80807086614173
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.345
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.24': {
+ bb: {
+ x: [
+ 0.24,
+ 0.0,
+ 37.66929133858268
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.35999999999999993
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.25': {
+ bb: {
+ x: [
+ 0.25,
+ 0.0,
+ 37.5246062992126
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.37499999999999994
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.26': {
+ bb: {
+ x: [
+ 0.26,
+ 0.0,
+ 37.3740157480315
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.38999999999999996
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.27': {
+ bb: {
+ x: [
+ 0.27,
+ 0.0,
+ 37.21751968503938
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.40499999999999997
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.28': {
+ bb: {
+ x: [
+ 0.28,
+ 0.0,
+ 37.05511811023622
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.42
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.29': {
+ bb: {
+ x: [
+ 0.29,
+ 0.0,
+ 36.88681102362205
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.43499999999999994
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.3': {
+ bb: {
+ x: [
+ 0.3,
+ 0.0,
+ 36.71259842519685
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.44999999999999996
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.31': {
+ bb: {
+ x: [
+ 0.31,
+ 0.0,
+ 36.53248031496063
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.46499999999999997
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.32': {
+ bb: {
+ x: [
+ 0.32,
+ 0.0,
+ 36.34645669291339
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.48
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.33': {
+ bb: {
+ x: [
+ 0.33,
+ 0.0,
+ 36.154527559055126
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.495
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.34': {
+ bb: {
+ x: [
+ 0.34,
+ 0.0,
+ 35.95669291338583
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.51
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.35': {
+ bb: {
+ x: [
+ 0.35,
+ 0.0,
+ 35.75295275590552
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.5249999999999999
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.36': {
+ bb: {
+ x: [
+ 0.36,
+ 0.0,
+ 35.54330708661418
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.5399999999999999
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.37': {
+ bb: {
+ x: [
+ 0.37,
+ 0.0,
+ 35.327755905511815
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.5549999999999999
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.38': {
+ bb: {
+ x: [
+ 0.38,
+ 0.0,
+ 35.10629921259843
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.57
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.39': {
+ bb: {
+ x: [
+ 0.39,
+ 0.0,
+ 34.87893700787402
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.585
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.4': {
+ bb: {
+ x: [
+ 0.4,
+ 0.0,
+ 34.64566929133859
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.6
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.41': {
+ bb: {
+ x: [
+ 0.41,
+ 0.0,
+ 34.40649606299213
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.6149999999999999
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.42': {
+ bb: {
+ x: [
+ 0.42,
+ 0.0,
+ 34.16141732283465
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.6299999999999999
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.43': {
+ bb: {
+ x: [
+ 0.43,
+ 0.0,
+ 33.91043307086615
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.6449999999999999
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.44': {
+ bb: {
+ x: [
+ 0.44,
+ 0.0,
+ 33.65354330708662
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.6599999999999999
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.45': {
+ bb: {
+ x: [
+ 0.45,
+ 0.0,
+ 33.390748031496074
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.6749999999999999
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.46': {
+ bb: {
+ x: [
+ 0.46,
+ 0.0,
+ 33.122047244094496
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.69
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.47': {
+ bb: {
+ x: [
+ 0.47,
+ 0.0,
+ 32.8474409448819
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.7049999999999998
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.48': {
+ bb: {
+ x: [
+ 0.48,
+ 0.0,
+ 32.56692913385828
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.7199999999999999
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.49': {
+ bb: {
+ x: [
+ 0.49,
+ 0.0,
+ 32.28051181102363
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.7349999999999999
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.5': {
+ bb: {
+ x: [
+ 0.5,
+ 0.0,
+ 31.988188976377963
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.7499999999999999
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.51': {
+ bb: {
+ x: [
+ 0.51,
+ 0.0,
+ 31.68996062992127
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.7649999999999999
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.52': {
+ bb: {
+ x: [
+ 0.52,
+ 0.0,
+ 31.38582677165355
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.7799999999999999
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.53': {
+ bb: {
+ x: [
+ 0.53,
+ 0.0,
+ 31.075787401574814
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.7949999999999999
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.54': {
+ bb: {
+ x: [
+ 0.54,
+ 0.0,
+ 30.759842519685048
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.8099999999999999
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.55': {
+ bb: {
+ x: [
+ 0.55,
+ 0.0,
+ 30.43799212598426
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.825
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.56': {
+ bb: {
+ x: [
+ 0.56,
+ 0.0,
+ 30.110236220472448
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.84
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.57': {
+ bb: {
+ x: [
+ 0.57,
+ 0.0,
+ 29.776574803149614
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.8549999999999998
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.58': {
+ bb: {
+ x: [
+ 0.58,
+ 0.0,
+ 29.43700787401576
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.8699999999999998
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.59': {
+ bb: {
+ x: [
+ 0.59,
+ 0.0,
+ 29.091535433070877
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.8849999999999998
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.6': {
+ bb: {
+ x: [
+ 0.6,
+ 0.0,
+ 28.740157480314974
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.8999999999999998
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.61': {
+ bb: {
+ x: [
+ 0.61,
+ 0.0,
+ 28.38287401574804
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.9149999999999998
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.62': {
+ bb: {
+ x: [
+ 0.62,
+ 0.0,
+ 28.01968503937009
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.9299999999999998
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.63': {
+ bb: {
+ x: [
+ 0.63,
+ 0.0,
+ 27.65059055118111
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.9449999999999998
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.64': {
+ bb: {
+ x: [
+ 0.64,
+ 0.0,
+ 27.27559055118111
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.9599999999999999
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.65': {
+ bb: {
+ x: [
+ 0.65,
+ 0.0,
+ 26.89468503937009
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.9749999999999999
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.66': {
+ bb: {
+ x: [
+ 0.66,
+ 0.0,
+ 26.50787401574804
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -0.9899999999999999
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.67': {
+ bb: {
+ x: [
+ 0.67,
+ 0.0,
+ 26.115157480314974
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.005
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.68': {
+ bb: {
+ x: [
+ 0.68,
+ 0.0,
+ 25.716535433070874
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.02
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.69': {
+ bb: {
+ x: [
+ 0.69,
+ 0.0,
+ 25.31200787401576
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.035
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.7': {
+ bb: {
+ x: [
+ 0.7,
+ 0.0,
+ 24.901574803149618
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.0499999999999998
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.71': {
+ bb: {
+ x: [
+ 0.71,
+ 0.0,
+ 24.48523622047245
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.065
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.72': {
+ bb: {
+ x: [
+ 0.72,
+ 0.0,
+ 24.062992125984266
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.08
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.73': {
+ bb: {
+ x: [
+ 0.73,
+ 0.0,
+ 23.634842519685055
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.0950000000000002
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.74': {
+ bb: {
+ x: [
+ 0.74,
+ 0.0,
+ 23.200787401574814
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.1100000000000003
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.75': {
+ bb: {
+ x: [
+ 0.75,
+ 0.0,
+ 22.76082677165355
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.1250000000000004
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.76': {
+ bb: {
+ x: [
+ 0.76,
+ 0.0,
+ 22.31496062992127
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.1400000000000006
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.77': {
+ bb: {
+ x: [
+ 0.77,
+ 0.0,
+ 21.863188976377963
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.1550000000000007
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.78': {
+ bb: {
+ x: [
+ 0.78,
+ 0.0,
+ 21.40551181102363
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.1700000000000008
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.79': {
+ bb: {
+ x: [
+ 0.79,
+ 0.0,
+ 20.941929133858277
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.185000000000001
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.8': {
+ bb: {
+ x: [
+ 0.8,
+ 0.0,
+ 20.472440944881896
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.200000000000001
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.81': {
+ bb: {
+ x: [
+ 0.81,
+ 0.0,
+ 19.997047244094492
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.2150000000000012
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.82': {
+ bb: {
+ x: [
+ 0.82,
+ 0.0,
+ 19.515748031496074
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.230000000000001
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.83': {
+ bb: {
+ x: [
+ 0.83,
+ 0.0,
+ 19.028543307086622
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.245000000000001
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.84': {
+ bb: {
+ x: [
+ 0.84,
+ 0.0,
+ 18.53543307086615
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.2600000000000011
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.85': {
+ bb: {
+ x: [
+ 0.85,
+ 0.0,
+ 18.03641732283465
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.2750000000000012
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.86': {
+ bb: {
+ x: [
+ 0.86,
+ 0.0,
+ 17.53149606299213
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.2900000000000014
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.87': {
+ bb: {
+ x: [
+ 0.87,
+ 0.0,
+ 17.02066929133859
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.3050000000000015
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.88': {
+ bb: {
+ x: [
+ 0.88,
+ 0.0,
+ 16.50393700787402
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.3200000000000016
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.89': {
+ bb: {
+ x: [
+ 0.89,
+ 0.0,
+ 15.981299212598426
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.3350000000000017
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.9': {
+ bb: {
+ x: [
+ 0.9,
+ 0.0,
+ 15.452755905511811
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.3500000000000019
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.91': {
+ bb: {
+ x: [
+ 0.91,
+ 0.0,
+ 14.918307086614174
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.365000000000002
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.92': {
+ bb: {
+ x: [
+ 0.92,
+ 0.0,
+ 14.377952755905511
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.3800000000000021
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.93': {
+ bb: {
+ x: [
+ 0.93,
+ 0.0,
+ 13.831692913385824
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.3950000000000022
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.94': {
+ bb: {
+ x: [
+ 0.94,
+ 0.0,
+ 13.27952755905512
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.4100000000000021
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.95': {
+ bb: {
+ x: [
+ 0.95,
+ 0.0,
+ 12.721456692913385
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.425000000000002
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.96': {
+ bb: {
+ x: [
+ 0.96,
+ 0.0,
+ 12.15748031496063
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.4400000000000022
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.97': {
+ bb: {
+ x: [
+ 0.97,
+ 0.0,
+ 11.587598425196848
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.4550000000000023
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.98': {
+ bb: {
+ x: [
+ 0.98,
+ 0.0,
+ 11.011811023622043
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.4700000000000024
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '0.99': {
+ bb: {
+ x: [
+ 0.99,
+ 0.0,
+ 10.430118110236215
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.4850000000000025
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.0': {
+ bb: {
+ x: [
+ 1.0,
+ 0.0,
+ 9.842519685039363
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.5000000000000027
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.01': {
+ bb: {
+ x: [
+ 1.01,
+ 0.0,
+ 9.249015748031487
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.5150000000000028
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.02': {
+ bb: {
+ x: [
+ 1.02,
+ 0.0,
+ 8.64960629921259
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.530000000000003
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.03': {
+ bb: {
+ x: [
+ 1.03,
+ 0.0,
+ 8.044291338582665
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.545000000000003
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.04': {
+ bb: {
+ x: [
+ 1.04,
+ 0.0,
+ 7.433070866141719
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.5600000000000032
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.05': {
+ bb: {
+ x: [
+ 1.05,
+ 0.0,
+ 6.815944881889749
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.5750000000000033
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.06': {
+ bb: {
+ x: [
+ 1.06,
+ 0.0,
+ 6.192913385826755
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.5900000000000034
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.07': {
+ bb: {
+ x: [
+ 1.07,
+ 0.0,
+ 5.563976377952738
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.6050000000000035
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.08': {
+ bb: {
+ x: [
+ 1.08,
+ 0.0,
+ 4.929133858267696
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.6200000000000037
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.09': {
+ bb: {
+ x: [
+ 1.09,
+ 0.0,
+ 4.2883858267716315
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.6350000000000038
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.1': {
+ bb: {
+ x: [
+ 1.1,
+ 0.0,
+ 3.6417322834645427
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.650000000000004
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.11': {
+ bb: {
+ x: [
+ 1.11,
+ 0.0,
+ 2.9891732283464307
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.665000000000004
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.12': {
+ bb: {
+ x: [
+ 1.12,
+ 0.0,
+ 2.330708661417295
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.6800000000000042
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.13': {
+ bb: {
+ x: [
+ 1.13,
+ 0.0,
+ 1.6663385826771504
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.6950000000000038
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.14': {
+ bb: {
+ x: [
+ 1.14,
+ 0.0,
+ 0.9960629921259674
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.710000000000004
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.15': {
+ bb: {
+ x: [
+ 1.15,
+ 0.0,
+ 0.31988188976376064
+ ],
+ v: [
+ 1.0,
+ 0.0,
+ -1.725000000000004
+ ],
+ x_b: [
+ 1.1547005383792517,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.16': {
+ bb: {
+ x: [
+ 1.1573502691896258,
+ 0.0,
+ 0.17985847125379134
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.8580762113533185
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.17': {
+ bb: {
+ x: [
+ 1.1623502691896257,
+ 0.0,
+ 0.5147309954086413
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.8430762113533184
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.18': {
+ bb: {
+ x: [
+ 1.1673502691896256,
+ 0.0,
+ 0.8436980077524677
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.8280762113533184
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.19': {
+ bb: {
+ x: [
+ 1.1723502691896255,
+ 0.0,
+ 1.1667595082852704
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.8130762113533184
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.2': {
+ bb: {
+ x: [
+ 1.1773502691896254,
+ 0.0,
+ 1.4839154970070494
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.7980762113533184
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.21': {
+ bb: {
+ x: [
+ 1.1823502691896253,
+ 0.0,
+ 1.7951659739178052
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.7830762113533184
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.22': {
+ bb: {
+ x: [
+ 1.1873502691896252,
+ 0.0,
+ 2.100510939017537
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.7680762113533184
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.23': {
+ bb: {
+ x: [
+ 1.192350269189625,
+ 0.0,
+ 2.3999503923062453
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.7530762113533184
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.24': {
+ bb: {
+ x: [
+ 1.197350269189625,
+ 0.0,
+ 2.6934843337839296
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.7380762113533184
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.25': {
+ bb: {
+ x: [
+ 1.2023502691896248,
+ 0.0,
+ 2.9811127634505907
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.7230762113533183
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.26': {
+ bb: {
+ x: [
+ 1.2073502691896247,
+ 0.0,
+ 3.2628356813062283
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.7080762113533183
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.27': {
+ bb: {
+ x: [
+ 1.2123502691896246,
+ 0.0,
+ 3.538653087350842
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.6930762113533183
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.28': {
+ bb: {
+ x: [
+ 1.2173502691896245,
+ 0.0,
+ 3.808564981584432
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.6780762113533183
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.29': {
+ bb: {
+ x: [
+ 1.2223502691896244,
+ 0.0,
+ 4.072571364006999
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.6630762113533183
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.3': {
+ bb: {
+ x: [
+ 1.2273502691896243,
+ 0.0,
+ 4.330672234618541
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.6480762113533183
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.31': {
+ bb: {
+ x: [
+ 1.2323502691896242,
+ 0.0,
+ 4.582867593419061
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.6330762113533183
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.32': {
+ bb: {
+ x: [
+ 1.237350269189624,
+ 0.0,
+ 4.829157440408556
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.6180762113533183
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.33': {
+ bb: {
+ x: [
+ 1.242350269189624,
+ 0.0,
+ 5.0695417755870285
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.6030762113533182
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.34': {
+ bb: {
+ x: [
+ 1.2473502691896239,
+ 0.0,
+ 5.304020598954477
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.5880762113533182
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.35': {
+ bb: {
+ x: [
+ 1.2523502691896238,
+ 0.0,
+ 5.532593910510901
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.5730762113533182
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.36': {
+ bb: {
+ x: [
+ 1.2573502691896237,
+ 0.0,
+ 5.755261710256303
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.5580762113533182
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.37': {
+ bb: {
+ x: [
+ 1.2623502691896236,
+ 0.0,
+ 5.9720239981906795
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.5430762113533182
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.38': {
+ bb: {
+ x: [
+ 1.2673502691896235,
+ 0.0,
+ 6.182880774314028
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.5280762113533185
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.39': {
+ bb: {
+ x: [
+ 1.2723502691896234,
+ 0.0,
+ 6.3878320386263585
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.5130762113533185
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.4': {
+ bb: {
+ x: [
+ 1.2773502691896232,
+ 0.0,
+ 6.586877791127665
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.4980762113533185
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.41': {
+ bb: {
+ x: [
+ 1.2823502691896231,
+ 0.0,
+ 6.780018031817948
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.48307621135331846
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.42': {
+ bb: {
+ x: [
+ 1.287350269189623,
+ 0.0,
+ 6.967252760697208
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.46807621135331845
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.43': {
+ bb: {
+ x: [
+ 1.292350269189623,
+ 0.0,
+ 7.148581977765444
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.45307621135331844
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.44': {
+ bb: {
+ x: [
+ 1.2973502691896228,
+ 0.0,
+ 7.324005683022656
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.4380762113533184
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.45': {
+ bb: {
+ x: [
+ 1.3023502691896227,
+ 0.0,
+ 7.493523876468845
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.4230762113533184
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.46': {
+ bb: {
+ x: [
+ 1.3073502691896226,
+ 0.0,
+ 7.65713655810401
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.4080762113533184
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.47': {
+ bb: {
+ x: [
+ 1.3123502691896225,
+ 0.0,
+ 7.81484372792815
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.3930762113533184
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.48': {
+ bb: {
+ x: [
+ 1.3173502691896224,
+ 0.0,
+ 7.966645385941268
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.37807621135331837
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.49': {
+ bb: {
+ x: [
+ 1.3223502691896223,
+ 0.0,
+ 8.112541532143362
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.36307621135331836
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.5': {
+ bb: {
+ x: [
+ 1.3273502691896222,
+ 0.0,
+ 8.252532166534433
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.34807621135331834
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.51': {
+ bb: {
+ x: [
+ 1.332350269189622,
+ 0.0,
+ 8.38661728911448
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.33307621135331833
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.52': {
+ bb: {
+ x: [
+ 1.337350269189622,
+ 0.0,
+ 8.514796899883503
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.3180762113533183
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.53': {
+ bb: {
+ x: [
+ 1.3423502691896219,
+ 0.0,
+ 8.637070998841502
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.3030762113533183
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.54': {
+ bb: {
+ x: [
+ 1.3473502691896218,
+ 0.0,
+ 8.753439585988477
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.2880762113533183
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.55': {
+ bb: {
+ x: [
+ 1.3523502691896216,
+ 0.0,
+ 8.86390266132443
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.2730762113533183
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.56': {
+ bb: {
+ x: [
+ 1.3573502691896215,
+ 0.0,
+ 8.968460224849359
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.25807621135331826
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.57': {
+ bb: {
+ x: [
+ 1.3623502691896214,
+ 0.0,
+ 9.067112276563263
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.24307621135331825
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.58': {
+ bb: {
+ x: [
+ 1.3673502691896213,
+ 0.0,
+ 9.159858816466144
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.22807621135331824
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.59': {
+ bb: {
+ x: [
+ 1.3723502691896212,
+ 0.0,
+ 9.246699844558002
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.21307621135331822
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.6': {
+ bb: {
+ x: [
+ 1.3773502691896211,
+ 0.0,
+ 9.327635360838835
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.1980762113533182
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.61': {
+ bb: {
+ x: [
+ 1.382350269189621,
+ 0.0,
+ 9.402665365308646
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.1830762113533182
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.62': {
+ bb: {
+ x: [
+ 1.387350269189621,
+ 0.0,
+ 9.471789857967433
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.16807621135331818
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.63': {
+ bb: {
+ x: [
+ 1.3923502691896208,
+ 0.0,
+ 9.535008838815195
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.1530762113533185
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.64': {
+ bb: {
+ x: [
+ 1.3973502691896207,
+ 0.0,
+ 9.592322307851934
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.1380762113533185
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.65': {
+ bb: {
+ x: [
+ 1.4023502691896206,
+ 0.0,
+ 9.64373026507765
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.12307621135331848
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.66': {
+ bb: {
+ x: [
+ 1.4073502691896205,
+ 0.0,
+ 9.689232710492343
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.10807621135331846
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.67': {
+ bb: {
+ x: [
+ 1.4123502691896204,
+ 0.0,
+ 9.728829644096011
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.09307621135331845
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.68': {
+ bb: {
+ x: [
+ 1.4173502691896203,
+ 0.0,
+ 9.762521065888656
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.07807621135331844
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.69': {
+ bb: {
+ x: [
+ 1.4223502691896202,
+ 0.0,
+ 9.790306975870278
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.06307621135331842
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.7': {
+ bb: {
+ x: [
+ 1.42735026918962,
+ 0.0,
+ 9.812187374040876
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.04807621135331841
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.71': {
+ bb: {
+ x: [
+ 1.43235026918962,
+ 0.0,
+ 9.82816226040045
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.0330762113533184
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.72': {
+ bb: {
+ x: [
+ 1.4373502691896198,
+ 0.0,
+ 9.838231634949
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.018076211353318383
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.73': {
+ bb: {
+ x: [
+ 1.4423502691896197,
+ 0.0,
+ 9.842395497686528
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ 0.00307621135331837
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.74': {
+ bb: {
+ x: [
+ 1.4473502691896196,
+ 0.0,
+ 9.84065384861303
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.011923788646681643
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.75': {
+ bb: {
+ x: [
+ 1.4523502691896195,
+ 0.0,
+ 9.83300668772851
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.026923788646681657
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.76': {
+ bb: {
+ x: [
+ 1.4573502691896194,
+ 0.0,
+ 9.819454015032965
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.04192378864668167
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.77': {
+ bb: {
+ x: [
+ 1.4623502691896193,
+ 0.0,
+ 9.799995830526399
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.05692378864668168
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.78': {
+ bb: {
+ x: [
+ 1.4673502691896192,
+ 0.0,
+ 9.774632134208806
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.0719237886466817
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.79': {
+ bb: {
+ x: [
+ 1.472350269189619,
+ 0.0,
+ 9.743362926080191
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.08692378864668171
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.8': {
+ bb: {
+ x: [
+ 1.477350269189619,
+ 0.0,
+ 9.706188206140553
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.10192378864668172
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.81': {
+ bb: {
+ x: [
+ 1.4823502691896189,
+ 0.0,
+ 9.663107974389892
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.11692378864668174
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.82': {
+ bb: {
+ x: [
+ 1.4873502691896188,
+ 0.0,
+ 9.614122230828205
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.13192378864668175
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.83': {
+ bb: {
+ x: [
+ 1.4923502691896187,
+ 0.0,
+ 9.559230975455495
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.14692378864668176
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.84': {
+ bb: {
+ x: [
+ 1.4973502691896186,
+ 0.0,
+ 9.498434208271764
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.16192378864668178
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.85': {
+ bb: {
+ x: [
+ 1.5023502691896184,
+ 0.0,
+ 9.431731929277007
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.1769237886466818
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.86': {
+ bb: {
+ x: [
+ 1.5073502691896183,
+ 0.0,
+ 9.359124138471225
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.1919237886466818
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.87': {
+ bb: {
+ x: [
+ 1.5123502691896182,
+ 0.0,
+ 9.280610835854421
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.20692378864668182
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.88': {
+ bb: {
+ x: [
+ 1.5173502691896181,
+ 0.0,
+ 9.196192021426596
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.2219237886466815
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.89': {
+ bb: {
+ x: [
+ 1.522350269189618,
+ 0.0,
+ 9.105867695187744
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.2369237886466815
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.9': {
+ bb: {
+ x: [
+ 1.527350269189618,
+ 0.0,
+ 9.00963785713787
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.2519237886466815
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.91': {
+ bb: {
+ x: [
+ 1.5323502691896178,
+ 0.0,
+ 8.907502507276972
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.26692378864668154
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.92': {
+ bb: {
+ x: [
+ 1.5373502691896177,
+ 0.0,
+ 8.79946164560505
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.28192378864668155
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.93': {
+ bb: {
+ x: [
+ 1.5423502691896176,
+ 0.0,
+ 8.685515272122105
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.29692378864668156
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.94': {
+ bb: {
+ x: [
+ 1.5473502691896175,
+ 0.0,
+ 8.565663386828135
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.3119237886466816
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.95': {
+ bb: {
+ x: [
+ 1.5523502691896174,
+ 0.0,
+ 8.439905989723142
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.3269237886466816
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.96': {
+ bb: {
+ x: [
+ 1.5573502691896173,
+ 0.0,
+ 8.308243080807125
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.3419237886466816
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.97': {
+ bb: {
+ x: [
+ 1.5623502691896172,
+ 0.0,
+ 8.170674660080087
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.3569237886466816
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.98': {
+ bb: {
+ x: [
+ 1.567350269189617,
+ 0.0,
+ 8.027200727542022
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.37192378864668163
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '1.99': {
+ bb: {
+ x: [
+ 1.572350269189617,
+ 0.0,
+ 7.877821283192935
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.38692378864668164
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.0': {
+ bb: {
+ x: [
+ 1.5773502691896168,
+ 0.0,
+ 7.722536327032824
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.40192378864668166
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.01': {
+ bb: {
+ x: [
+ 1.5823502691896167,
+ 0.0,
+ 7.561345859061692
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.41692378864668134
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.02': {
+ bb: {
+ x: [
+ 1.5873502691896169,
+ 0.0,
+ 7.39424987927953
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.4319237886466817
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.03': {
+ bb: {
+ x: [
+ 1.5923502691896168,
+ 0.0,
+ 7.2212483876863525
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.44692378864668136
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.04': {
+ bb: {
+ x: [
+ 1.5973502691896169,
+ 0.0,
+ 7.0423413842821425
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.4619237886466817
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.05': {
+ bb: {
+ x: [
+ 1.6023502691896168,
+ 0.0,
+ 6.8575288690669165
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.4769237886466814
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.06': {
+ bb: {
+ x: [
+ 1.6073502691896169,
+ 0.0,
+ 6.666810842040659
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.49192378864668174
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.07': {
+ bb: {
+ x: [
+ 1.6123502691896168,
+ 0.0,
+ 6.470187303203388
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.5069237886466814
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.08': {
+ bb: {
+ x: [
+ 1.6173502691896169,
+ 0.0,
+ 6.2676582525550835
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.5219237886466818
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.09': {
+ bb: {
+ x: [
+ 1.6223502691896168,
+ 0.0,
+ 6.059223690095764
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.5369237886466814
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.1': {
+ bb: {
+ x: [
+ 1.627350269189617,
+ 0.0,
+ 5.844883615825412
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.5519237886466818
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.11': {
+ bb: {
+ x: [
+ 1.6323502691896168,
+ 0.0,
+ 5.6246380297440455
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.5669237886466815
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.12': {
+ bb: {
+ x: [
+ 1.637350269189617,
+ 0.0,
+ 5.398486931851647
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.5819237886466818
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.13': {
+ bb: {
+ x: [
+ 1.6423502691896168,
+ 0.0,
+ 5.166430322148233
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.5969237886466815
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.14': {
+ bb: {
+ x: [
+ 1.647350269189617,
+ 0.0,
+ 4.928468200633786
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.6119237886466818
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.15': {
+ bb: {
+ x: [
+ 1.6523502691896168,
+ 0.0,
+ 4.684600567308325
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.6269237886466815
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.16': {
+ bb: {
+ x: [
+ 1.657350269189617,
+ 0.0,
+ 4.434827422171831
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.6419237886466819
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.17': {
+ bb: {
+ x: [
+ 1.6623502691896168,
+ 0.0,
+ 4.179148765224324
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.6569237886466816
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.18': {
+ bb: {
+ x: [
+ 1.667350269189617,
+ 0.0,
+ 3.917564596465782
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.6719237886466819
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.19': {
+ bb: {
+ x: [
+ 1.6723502691896168,
+ 0.0,
+ 3.6500749158962282
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.6869237886466816
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.2': {
+ bb: {
+ x: [
+ 1.677350269189617,
+ 0.0,
+ 3.3766797235156387
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.7019237886466819
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.21': {
+ bb: {
+ x: [
+ 1.6823502691896168,
+ 0.0,
+ 3.0973790193240376
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.7169237886466816
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.22': {
+ bb: {
+ x: [
+ 1.687350269189617,
+ 0.0,
+ 2.8121728033214004
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.731923788646682
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.23': {
+ bb: {
+ x: [
+ 1.6923502691896168,
+ 0.0,
+ 2.5210610755077525
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.7469237886466816
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.24': {
+ bb: {
+ x: [
+ 1.697350269189617,
+ 0.0,
+ 2.2240438358830676
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.761923788646682
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.25': {
+ bb: {
+ x: [
+ 1.7023502691896168,
+ 0.0,
+ 1.9211210844473727
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.7769237886466817
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.26': {
+ bb: {
+ x: [
+ 1.7073502691896167,
+ 0.0,
+ 1.6122928212006544
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.7919237886466813
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.27': {
+ bb: {
+ x: [
+ 1.7123502691896169,
+ 0.0,
+ 1.2975590461428985
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.8069237886466817
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.28': {
+ bb: {
+ x: [
+ 1.7173502691896168,
+ 0.0,
+ 0.9769197592741332
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.8219237886466814
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.29': {
+ bb: {
+ x: [
+ 1.7223502691896169,
+ 0.0,
+ 0.6503749605943299
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.8369237886466817
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.3': {
+ bb: {
+ x: [
+ 1.7273502691896168,
+ 0.0,
+ 0.31792465010351745
+ ],
+ v: [
+ 0.5,
+ 0.0,
+ -0.8519237886466814
+ ],
+ x_b: [
+ 1.732050807568879,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.31': {
+ bb: {
+ x: [
+ 1.7322005383792525,
+ 0.0,
+ 0.010199698395215402
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.4321143170299793
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.32': {
+ bb: {
+ x: [
+ 1.7347005383792524,
+ 0.0,
+ 0.17737068935189665
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.41711431702997964
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.33': {
+ bb: {
+ x: [
+ 1.7372005383792524,
+ 0.0,
+ 0.3386361684975615
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.4021143170299793
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.34': {
+ bb: {
+ x: [
+ 1.7397005383792523,
+ 0.0,
+ 0.4939961358321958
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.3871143170299796
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.35': {
+ bb: {
+ x: [
+ 1.7422005383792523,
+ 0.0,
+ 0.6434505913558131
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.37211431702997927
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.36': {
+ bb: {
+ x: [
+ 1.7447005383792522,
+ 0.0,
+ 0.7869995350684004
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.3571143170299796
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.37': {
+ bb: {
+ x: [
+ 1.7472005383792522,
+ 0.0,
+ 0.9246429669699702
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.34211431702997924
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.38': {
+ bb: {
+ x: [
+ 1.749700538379252,
+ 0.0,
+ 1.0563808870605105
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.32711431702997956
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.39': {
+ bb: {
+ x: [
+ 1.752200538379252,
+ 0.0,
+ 1.1822132953400326
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.3121143170299792
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.4': {
+ bb: {
+ x: [
+ 1.754700538379252,
+ 0.0,
+ 1.3021401918085258
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.29711431702997954
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.41': {
+ bb: {
+ x: [
+ 1.757200538379252,
+ 0.0,
+ 1.4161615764660007
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.2821143170299792
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.42': {
+ bb: {
+ x: [
+ 1.7597005383792519,
+ 0.0,
+ 1.524277449312447
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.2671143170299795
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.43': {
+ bb: {
+ x: [
+ 1.7622005383792518,
+ 0.0,
+ 1.6264878103478742
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.25211431702997916
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.44': {
+ bb: {
+ x: [
+ 1.7647005383792518,
+ 0.0,
+ 1.7227926595722731
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.23711431702997948
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.45': {
+ bb: {
+ x: [
+ 1.7672005383792517,
+ 0.0,
+ 1.813191996985653
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.22211431702997914
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.46': {
+ bb: {
+ x: [
+ 1.7697005383792517,
+ 0.0,
+ 1.8976858225880051
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.20711431702997946
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.47': {
+ bb: {
+ x: [
+ 1.7722005383792516,
+ 0.0,
+ 1.9762741363793372
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.1921143170299791
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.48': {
+ bb: {
+ x: [
+ 1.7747005383792516,
+ 0.0,
+ 2.0489569383596424
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.17711431702997943
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.49': {
+ bb: {
+ x: [
+ 1.7772005383792515,
+ 0.0,
+ 2.1157342285289276
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.16211431702997908
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.5': {
+ bb: {
+ x: [
+ 1.7797005383792515,
+ 0.0,
+ 2.1766060068871855
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.1471143170299794
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.51': {
+ bb: {
+ x: [
+ 1.7822005383792514,
+ 0.0,
+ 2.2315722734344203
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.13211431702997972
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.52': {
+ bb: {
+ x: [
+ 1.7847005383792514,
+ 0.0,
+ 2.2806330281706337
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.11711431702997938
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.53': {
+ bb: {
+ x: [
+ 1.7872005383792513,
+ 0.0,
+ 2.3237882710958218
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.1021143170299797
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.54': {
+ bb: {
+ x: [
+ 1.7897005383792512,
+ 0.0,
+ 2.361038002209988
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.08711431702997935
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.55': {
+ bb: {
+ x: [
+ 1.7922005383792512,
+ 0.0,
+ 2.3923822215131287
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.07211431702997967
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.56': {
+ bb: {
+ x: [
+ 1.7947005383792511,
+ 0.0,
+ 2.4178209290052473
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.05711431702997932
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.57': {
+ bb: {
+ x: [
+ 1.797200538379251,
+ 0.0,
+ 2.4373541246863413
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.04211431702997964
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.58': {
+ bb: {
+ x: [
+ 1.799700538379251,
+ 0.0,
+ 2.450981808556412
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.027114317029979296
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.59': {
+ bb: {
+ x: [
+ 1.802200538379251,
+ 0.0,
+ 2.4587039806154594
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ 0.012114317029979615
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.6': {
+ bb: {
+ x: [
+ 1.804700538379251,
+ 0.0,
+ 2.4605206408634825
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.002885682970020731
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.61': {
+ bb: {
+ x: [
+ 1.8072005383792509,
+ 0.0,
+ 2.4564317893004826
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.01788568297002041
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.62': {
+ bb: {
+ x: [
+ 1.8097005383792508,
+ 0.0,
+ 2.446437425926458
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.03288568297002076
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.63': {
+ bb: {
+ x: [
+ 1.8122005383792508,
+ 0.0,
+ 2.430537550741411
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.04788568297002044
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.64': {
+ bb: {
+ x: [
+ 1.8147005383792507,
+ 0.0,
+ 2.4087321637453396
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.06288568297002078
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.65': {
+ bb: {
+ x: [
+ 1.8172005383792507,
+ 0.0,
+ 2.381021264938245
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.07788568297002046
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.66': {
+ bb: {
+ x: [
+ 1.8197005383792506,
+ 0.0,
+ 2.3474048543201262
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.09288568297002081
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.67': {
+ bb: {
+ x: [
+ 1.8222005383792506,
+ 0.0,
+ 2.307882931890985
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.10788568297002049
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.68': {
+ bb: {
+ x: [
+ 1.8247005383792505,
+ 0.0,
+ 2.2624554976508184
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.12288568297002084
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.69': {
+ bb: {
+ x: [
+ 1.8272005383792504,
+ 0.0,
+ 2.21112255159963
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.13788568297002052
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.7': {
+ bb: {
+ x: [
+ 1.8297005383792504,
+ 0.0,
+ 2.1538840937374157
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.15288568297002086
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.71': {
+ bb: {
+ x: [
+ 1.8322005383792503,
+ 0.0,
+ 2.090740124064181
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.16788568297002054
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.72': {
+ bb: {
+ x: [
+ 1.8347005383792503,
+ 0.0,
+ 2.021690642579919
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.1828856829700209
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.73': {
+ bb: {
+ x: [
+ 1.8372005383792502,
+ 0.0,
+ 1.946735649284637
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.19788568297002057
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.74': {
+ bb: {
+ x: [
+ 1.8397005383792502,
+ 0.0,
+ 1.865875144178328
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.21288568297002092
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.75': {
+ bb: {
+ x: [
+ 1.8422005383792501,
+ 0.0,
+ 1.7791091272609987
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.2278856829700206
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.76': {
+ bb: {
+ x: [
+ 1.84470053837925,
+ 0.0,
+ 1.686437598532646
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.24288568297002028
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.77': {
+ bb: {
+ x: [
+ 1.84720053837925,
+ 0.0,
+ 1.5878605579932659
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.2578856829700206
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.78': {
+ bb: {
+ x: [
+ 1.84970053837925,
+ 0.0,
+ 1.4833780056428665
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.2728856829700203
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.79': {
+ bb: {
+ x: [
+ 1.85220053837925,
+ 0.0,
+ 1.3729899414814386
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.28788568297002065
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.8': {
+ bb: {
+ x: [
+ 1.8547005383792499,
+ 0.0,
+ 1.2566963655089922
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.30288568297002033
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.81': {
+ bb: {
+ x: [
+ 1.8572005383792498,
+ 0.0,
+ 1.134497277725517
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.3178856829700207
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.82': {
+ bb: {
+ x: [
+ 1.8597005383792498,
+ 0.0,
+ 1.0063926781310233
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.33288568297002036
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.83': {
+ bb: {
+ x: [
+ 1.8622005383792497,
+ 0.0,
+ 0.8723825667255003
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.3478856829700207
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.84': {
+ bb: {
+ x: [
+ 1.8647005383792497,
+ 0.0,
+ 0.7324669435089598
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.3628856829700204
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.85': {
+ bb: {
+ x: [
+ 1.8672005383792496,
+ 0.0,
+ 0.5866458084813894
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.37788568297002073
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.86': {
+ bb: {
+ x: [
+ 1.8697005383792495,
+ 0.0,
+ 0.4349191616428018
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.3928856829700204
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.87': {
+ bb: {
+ x: [
+ 1.8722005383792495,
+ 0.0,
+ 0.27728700299318376
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.40788568297002076
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.88': {
+ bb: {
+ x: [
+ 1.8747005383792494,
+ 0.0,
+ 0.11374933253254924
+ ],
+ v: [
+ 0.25,
+ 0.0,
+ -0.42288568297002044
+ ],
+ x_b: [
+ 1.8763883748662857,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.89': {
+ bb: {
+ x: [
+ 1.8767944566227692,
+ 0.0,
+ 0.02737948501553115
+ ],
+ v: [
+ 0.125,
+ 0.0,
+ 0.21163336986830958
+ ],
+ x_b: [
+ 1.9124727666906374,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.9': {
+ bb: {
+ x: [
+ 1.8780444566227692,
+ 0.0,
+ 0.10774695346761987
+ ],
+ v: [
+ 0.125,
+ 0.0,
+ 0.1966333698683099
+ ],
+ x_b: [
+ 1.9124727666906374,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.91': {
+ bb: {
+ x: [
+ 1.8792944566227692,
+ 0.0,
+ 0.1822089101086884
+ ],
+ v: [
+ 0.125,
+ 0.0,
+ 0.18163336986830955
+ ],
+ x_b: [
+ 1.9124727666906374,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.92': {
+ bb: {
+ x: [
+ 1.8805444566227691,
+ 0.0,
+ 0.2507653549387301
+ ],
+ v: [
+ 0.125,
+ 0.0,
+ 0.16663336986830987
+ ],
+ x_b: [
+ 1.9124727666906374,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.93': {
+ bb: {
+ x: [
+ 1.8817944566227691,
+ 0.0,
+ 0.3134162879577511
+ ],
+ v: [
+ 0.125,
+ 0.0,
+ 0.15163336986830953
+ ],
+ x_b: [
+ 1.9124727666906374,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.94': {
+ bb: {
+ x: [
+ 1.883044456622769,
+ 0.0,
+ 0.37016170916574587
+ ],
+ v: [
+ 0.125,
+ 0.0,
+ 0.13663336986830985
+ ],
+ x_b: [
+ 1.9124727666906374,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.95': {
+ bb: {
+ x: [
+ 1.884294456622769,
+ 0.0,
+ 0.42100161856271934
+ ],
+ v: [
+ 0.125,
+ 0.0,
+ 0.1216333698683095
+ ],
+ x_b: [
+ 1.9124727666906374,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.96': {
+ bb: {
+ x: [
+ 1.885544456622769,
+ 0.0,
+ 0.4659360161486671
+ ],
+ v: [
+ 0.125,
+ 0.0,
+ 0.10663336986830982
+ ],
+ x_b: [
+ 1.9124727666906374,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.97': {
+ bb: {
+ x: [
+ 1.886794456622769,
+ 0.0,
+ 0.504964901923593
+ ],
+ v: [
+ 0.125,
+ 0.0,
+ 0.09163336986830947
+ ],
+ x_b: [
+ 1.9124727666906374,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.98': {
+ bb: {
+ x: [
+ 1.888044456622769,
+ 0.0,
+ 0.5380882758874937
+ ],
+ v: [
+ 0.125,
+ 0.0,
+ 0.07663336986830979
+ ],
+ x_b: [
+ 1.9124727666906374,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '2.99': {
+ bb: {
+ x: [
+ 1.889294456622769,
+ 0.0,
+ 0.5653061380403721
+ ],
+ v: [
+ 0.125,
+ 0.0,
+ 0.061633369868309446
+ ],
+ x_b: [
+ 1.9124727666906374,
+ 0.0,
+ 0.0
+ ]
+ }
+ },
+ '3.0': {
+ bb: {
+ x: [
+ 1.890544456622769,
+ 0.0,
+ 0.5866184883822259
+ ],
+ v: [
+ 0.125,
+ 0.0,
+ 0.046633369868309765
+ ],
+ x_b: [
+ 1.9124727666906374,
+ 0.0,
+ 0.0
+ ]
+ }
+ }
+}
diff --git a/tests/data/BouncingBall3D/test_results b/tests/data/BouncingBall3D/test_results
index 4028d81..370f416 100644
--- a/tests/data/BouncingBall3D/test_results
+++ b/tests/data/BouncingBall3D/test_results
@@ -1,2411 +1,1511 @@
{
-header : {
- case : 'restitution',
- dateTime : '1924-01-14T00:00:00',
- cases : 'BouncingBall3D',
- file : 'BouncingBall3D.cases',
- casesDate : '1924-01-13T00:00:00',
- timeUnit : 'second',
- timeFactor : 1000000000.0},
-
-0.01 : {
- bb : {
- e : 0.5,
- g : 9.81,
- x : [0.01,0.0,39.35076771653544],
-
- v : [1.0,0.0,-0.0981],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.02 : {
- bb : {
- x : [0.02,0.0,39.292834645669295],
-
- v : [1.0,0.0,-0.1962],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.03 : {
- bb : {
- x : [0.03,0.0,39.196279527559064],
-
- v : [1.0,0.0,-0.2943],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.04 : {
- bb : {
- x : [0.04,0.0,39.061102362204736],
-
- v : [1.0,0.0,-0.3924],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.05 : {
- bb : {
- x : [0.05,0.0,38.88730314960631],
-
- v : [1.0,0.0,-0.49050000000000005],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.06 : {
- bb : {
- x : [0.06,0.0,38.67488188976379],
-
- v : [1.0,0.0,-0.5886],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.07 : {
- bb : {
- x : [0.07,0.0,38.42383858267718],
-
- v : [1.0,0.0,-0.6867000000000001],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.08 : {
- bb : {
- x : [0.08,0.0,38.13417322834646],
-
- v : [1.0,0.0,-0.7848],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.09 : {
- bb : {
- x : [0.09,0.0,37.80588582677166],
-
- v : [1.0,0.0,-0.8829],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.1 : {
- bb : {
- x : [0.1,0.0,37.43897637795276],
-
- v : [1.0,0.0,-0.9810000000000001],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.11 : {
- bb : {
- x : [0.11,0.0,37.03344488188977],
-
- v : [1.0,0.0,-1.0791],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.12 : {
- bb : {
- x : [0.12,0.0,36.58929133858268],
-
- v : [1.0,0.0,-1.1771999999999998],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.13 : {
- bb : {
- x : [0.13,0.0,36.106515748031505],
-
- v : [1.0,0.0,-1.2752999999999999],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.14 : {
- bb : {
- x : [0.14,0.0,35.58511811023623],
-
- v : [1.0,0.0,-1.3734],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.15 : {
- bb : {
- x : [0.15,0.0,35.02509842519686],
-
- v : [1.0,0.0,-1.4714999999999998],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.16 : {
- bb : {
- x : [0.16,0.0,34.4264566929134],
-
- v : [1.0,0.0,-1.5695999999999999],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.17 : {
- bb : {
- x : [0.17,0.0,33.78919291338584],
-
- v : [1.0,0.0,-1.6677],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.18 : {
- bb : {
- x : [0.18,0.0,33.113307086614185],
-
- v : [1.0,0.0,-1.7657999999999998],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.19 : {
- bb : {
- x : [0.19,0.0,32.39879921259844],
-
- v : [1.0,0.0,-1.8639],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.2 : {
- bb : {
- x : [0.2,0.0,31.645669291338592],
-
- v : [1.0,0.0,-1.962],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.21 : {
- bb : {
- x : [0.21,0.0,30.85391732283466],
-
- v : [1.0,0.0,-2.0601],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.22 : {
- bb : {
- x : [0.22,0.0,30.023543307086626],
-
- v : [1.0,0.0,-2.1582],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.23 : {
- bb : {
- x : [0.23,0.0,29.1545472440945],
-
- v : [1.0,0.0,-2.2563],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.24 : {
- bb : {
- x : [0.24,0.0,28.24692913385828],
-
- v : [1.0,0.0,-2.3543999999999996],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.25 : {
- bb : {
- x : [0.25,0.0,27.300688976377963],
-
- v : [1.0,0.0,-2.4524999999999997],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.26 : {
- bb : {
- x : [0.26,0.0,26.315826771653555],
-
- v : [1.0,0.0,-2.5505999999999998],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.27 : {
- bb : {
- x : [0.27,0.0,25.292342519685054],
-
- v : [1.0,0.0,-2.6487],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.28 : {
- bb : {
- x : [0.28,0.0,24.230236220472456],
-
- v : [1.0,0.0,-2.7468],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.29 : {
- bb : {
- x : [0.29,0.0,23.129507874015765],
-
- v : [1.0,0.0,-2.8448999999999995],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.3 : {
- bb : {
- x : [0.3,0.0,21.990157480314977],
-
- v : [1.0,0.0,-2.9429999999999996],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.31 : {
- bb : {
- x : [0.31,0.0,20.812185039370096],
-
- v : [1.0,0.0,-3.0410999999999997],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.32 : {
- bb : {
- x : [0.32,0.0,19.595590551181118],
-
- v : [1.0,0.0,-3.1391999999999998],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.33 : {
- bb : {
- x : [0.33,0.0,18.340374015748047],
-
- v : [1.0,0.0,-3.2373],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.34 : {
- bb : {
- x : [0.34,0.0,17.04653543307088],
-
- v : [1.0,0.0,-3.3354],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.35 : {
- bb : {
- x : [0.35,0.0,15.714074803149627],
-
- v : [1.0,0.0,-3.4334999999999996],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.36 : {
- bb : {
- x : [0.36,0.0,14.342992125984273],
-
- v : [1.0,0.0,-3.5315999999999996],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.37 : {
- bb : {
- x : [0.37,0.0,12.933287401574823],
-
- v : [1.0,0.0,-3.6296999999999997],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.38 : {
- bb : {
- x : [0.38,0.0,11.484960629921279],
-
- v : [1.0,0.0,-3.7278],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.39 : {
- bb : {
- x : [0.39,0.0,9.99801181102364],
-
- v : [1.0,0.0,-3.8259],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.4 : {
- bb : {
- x : [0.4,0.0,8.472440944881907],
-
- v : [1.0,0.0,-3.924],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.41 : {
- bb : {
- x : [0.41,0.0,6.908248031496088],
-
- v : [1.0,0.0,-4.022099999999999],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.42 : {
- bb : {
- x : [0.42,0.0,5.305433070866167],
-
- v : [1.0,0.0,-4.1202],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.43 : {
- bb : {
- x : [0.43,0.0,3.66399606299215],
-
- v : [1.0,0.0,-4.2183],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.44 : {
- bb : {
- x : [0.44,0.0,1.9839370078740388],
-
- v : [1.0,0.0,-4.316400000000001],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.45 : {
- bb : {
- x : [0.45,0.0,0.26525590551183287],
-
- v : [1.0,0.0,-4.414500000000001],
-
- x_b : [0.4515236409857309,0.0,0.0]}},
-
-0.46 : {
- bb : {
- x : [0.45576182049286545,0.0,0.7252115538706296],
-
- v : [0.5,0.0,2.1315703771050307],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.47 : {
- bb : {
- x : [0.4607618204928654,0.0,1.545101466116701],
-
- v : [0.5,0.0,2.033470377105031],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.48 : {
- bb : {
- x : [0.4657618204928654,0.0,2.3263693311186824],
-
- v : [0.5,0.0,1.935370377105031],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.49 : {
- bb : {
- x : [0.4707618204928654,0.0,3.069015148876569],
-
- v : [0.5,0.0,1.837270377105031],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.5 : {
- bb : {
- x : [0.4757618204928654,0.0,3.7730389193903613],
-
- v : [0.5,0.0,1.7391703771050309],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.51 : {
- bb : {
- x : [0.4807618204928654,0.0,4.438440642660058],
-
- v : [0.5,0.0,1.6410703771050308],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.52 : {
- bb : {
- x : [0.4857618204928654,0.0,5.065220318685662],
-
- v : [0.5,0.0,1.5429703771050307],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.53 : {
- bb : {
- x : [0.49076182049286543,0.0,5.65337794746717],
-
- v : [0.5,0.0,1.4448703771050306],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.54 : {
- bb : {
- x : [0.49576182049286543,0.0,6.202913529004584],
-
- v : [0.5,0.0,1.3467703771050306],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.55 : {
- bb : {
- x : [0.5007618204928654,0.0,6.713827063297904],
-
- v : [0.5,0.0,1.2486703771050305],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.56 : {
- bb : {
- x : [0.5057618204928654,0.0,7.186118550347129],
-
- v : [0.5,0.0,1.1505703771050304],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.57 : {
- bb : {
- x : [0.5107618204928654,0.0,7.619787990152255],
-
- v : [0.5,0.0,1.0524703771050314],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.58 : {
- bb : {
- x : [0.5157618204928655,0.0,8.014835382713292],
-
- v : [0.5,0.0,0.9543703771050314],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.59 : {
- bb : {
- x : [0.5207618204928655,0.0,8.371260728030233],
-
- v : [0.5,0.0,0.8562703771050313],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.6 : {
- bb : {
- x : [0.5257618204928655,0.0,8.689064026103079],
-
- v : [0.5,0.0,0.7581703771050312],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.61 : {
- bb : {
- x : [0.5307618204928655,0.0,8.968245276931832],
-
- v : [0.5,0.0,0.6600703771050311],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.62 : {
- bb : {
- x : [0.5357618204928655,0.0,9.20880448051649],
-
- v : [0.5,0.0,0.5619703771050311],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.63 : {
- bb : {
- x : [0.5407618204928655,0.0,9.410741636857054],
-
- v : [0.5,0.0,0.463870377105031],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.64 : {
- bb : {
- x : [0.5457618204928655,0.0,9.574056745953524],
-
- v : [0.5,0.0,0.3657703771050309],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.65 : {
- bb : {
- x : [0.5507618204928655,0.0,9.698749807805898],
-
- v : [0.5,0.0,0.26767037710503083],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.66 : {
- bb : {
- x : [0.5557618204928655,0.0,9.784820822414177],
-
- v : [0.5,0.0,0.16957037710503076],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.67 : {
- bb : {
- x : [0.5607618204928655,0.0,9.832269789778362],
-
- v : [0.5,0.0,0.07147037710503067],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.68 : {
- bb : {
- x : [0.5657618204928655,0.0,9.841096709898453],
-
- v : [0.5,0.0,-0.026629622894969424],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.69 : {
- bb : {
- x : [0.5707618204928655,0.0,9.811301582774451],
-
- v : [0.5,0.0,-0.12472962289496843],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.7 : {
- bb : {
- x : [0.5757618204928655,0.0,9.742884408406352],
-
- v : [0.5,0.0,-0.22282962289496852],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.71 : {
- bb : {
- x : [0.5807618204928655,0.0,9.63584518679416],
-
- v : [0.5,0.0,-0.3209296228949686],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.72 : {
- bb : {
- x : [0.5857618204928655,0.0,9.490183917937873],
-
- v : [0.5,0.0,-0.4190296228949687],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.73 : {
- bb : {
- x : [0.5907618204928655,0.0,9.305900601837491],
-
- v : [0.5,0.0,-0.5171296228949688],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.74 : {
- bb : {
- x : [0.5957618204928655,0.0,9.082995238493016],
-
- v : [0.5,0.0,-0.6152296228949689],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.75 : {
- bb : {
- x : [0.6007618204928655,0.0,8.821467827904446],
-
- v : [0.5,0.0,-0.7133296228949689],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.76 : {
- bb : {
- x : [0.6057618204928655,0.0,8.52131837007178],
-
- v : [0.5,0.0,-0.811429622894969],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.77 : {
- bb : {
- x : [0.6107618204928655,0.0,8.18254686499502],
-
- v : [0.5,0.0,-0.9095296228949691],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.78 : {
- bb : {
- x : [0.6157618204928655,0.0,7.805153312674166],
-
- v : [0.5,0.0,-1.0076296228949693],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.79 : {
- bb : {
- x : [0.6207618204928655,0.0,7.389137713109217],
-
- v : [0.5,0.0,-1.1057296228949693],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.8 : {
- bb : {
- x : [0.6257618204928656,0.0,6.934500066300174],
-
- v : [0.5,0.0,-1.2038296228949694],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.81 : {
- bb : {
- x : [0.6307618204928656,0.0,6.441240372247036],
-
- v : [0.5,0.0,-1.3019296228949695],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.82 : {
- bb : {
- x : [0.6357618204928654,0.0,5.90935863094981],
-
- v : [0.5,0.0,-1.4000296228949685],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.83 : {
- bb : {
- x : [0.6407618204928655,0.0,5.338854842408484],
-
- v : [0.5,0.0,-1.4981296228949685],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.84 : {
- bb : {
- x : [0.6457618204928655,0.0,4.729729006623062],
-
- v : [0.5,0.0,-1.5962296228949686],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.85 : {
- bb : {
- x : [0.6507618204928655,0.0,4.081981123593547],
-
- v : [0.5,0.0,-1.6943296228949687],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.86 : {
- bb : {
- x : [0.6557618204928655,0.0,3.395611193319936],
-
- v : [0.5,0.0,-1.7924296228949688],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.87 : {
- bb : {
- x : [0.6607618204928655,0.0,2.6706192158022315],
-
- v : [0.5,0.0,-1.8905296228949688],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.88 : {
- bb : {
- x : [0.6657618204928655,0.0,1.9070051910404322],
-
- v : [0.5,0.0,-1.988629622894969],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.89 : {
- bb : {
- x : [0.6707618204928655,0.0,1.1047691190345383],
-
- v : [0.5,0.0,-2.086729622894969],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.9 : {
- bb : {
- x : [0.6757618204928655,0.0,0.26391099978454996],
-
- v : [0.5,0.0,-2.184829622894969],
-
- x_b : [0.6772854614785964,0.0,0.0]}},
-
-0.91 : {
- bb : {
- x : [0.6790236409857309,0.0,0.29378207670733264],
-
- v : [0.25,0.0,1.0391555656575457],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-0.92 : {
- bb : {
- x : [0.6815236409857308,0.0,0.6835874175173903],
-
- v : [0.25,0.0,0.9410555656575457],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-0.93 : {
- bb : {
- x : [0.6840236409857308,0.0,1.0347707110833533],
-
- v : [0.25,0.0,0.8429555656575456],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-0.94 : {
- bb : {
- x : [0.6865236409857307,0.0,1.3473319574052187],
-
- v : [0.25,0.0,0.7448555656575466],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-0.95 : {
- bb : {
- x : [0.6890236409857307,0.0,1.6212711564829934],
-
- v : [0.25,0.0,0.6467555656575465],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-0.96 : {
- bb : {
- x : [0.6915236409857306,0.0,1.8565883083166732],
-
- v : [0.25,0.0,0.5486555656575465],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-0.97 : {
- bb : {
- x : [0.6940236409857305,0.0,2.0532834129062585],
-
- v : [0.25,0.0,0.4505555656575464],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-0.98 : {
- bb : {
- x : [0.6965236409857305,0.0,2.211356470251749],
-
- v : [0.25,0.0,0.3524555656575463],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-0.99 : {
- bb : {
- x : [0.6990236409857304,0.0,2.3308074803531453],
-
- v : [0.25,0.0,0.25435556565754625],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-1.0 : {
- bb : {
- x : [0.7015236409857304,0.0,2.411636443210447],
-
- v : [0.25,0.0,0.15625556565754617],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-1.01 : {
- bb : {
- x : [0.7040236409857303,0.0,2.4538433588236543],
-
- v : [0.25,0.0,0.05815556565754608],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-1.02 : {
- bb : {
- x : [0.7065236409857303,0.0,2.457428227192767],
-
- v : [0.25,0.0,-0.03994443434245401],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-1.03 : {
- bb : {
- x : [0.7090236409857302,0.0,2.422391048317785],
-
- v : [0.25,0.0,-0.13804443434245411],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-1.04 : {
- bb : {
- x : [0.7115236409857302,0.0,2.3487318221987086],
-
- v : [0.25,0.0,-0.2361444343424542],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-1.05 : {
- bb : {
- x : [0.7140236409857301,0.0,2.2364505488355375],
-
- v : [0.25,0.0,-0.33424443434245427],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-1.06 : {
- bb : {
- x : [0.7165236409857301,0.0,2.085547228228272],
-
- v : [0.25,0.0,-0.43234443434245434],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-1.07 : {
- bb : {
- x : [0.71902364098573,0.0,1.896021860376912],
-
- v : [0.25,0.0,-0.5304444343424545],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-1.08 : {
- bb : {
- x : [0.72152364098573,0.0,1.6678744452814571],
-
- v : [0.25,0.0,-0.6285444343424545],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-1.09 : {
- bb : {
- x : [0.7240236409857299,0.0,1.401104982941908],
-
- v : [0.25,0.0,-0.7266444343424546],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-1.1 : {
- bb : {
- x : [0.7265236409857299,0.0,1.095713473358264],
-
- v : [0.25,0.0,-0.8247444343424547],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-1.11 : {
- bb : {
- x : [0.7290236409857298,0.0,0.7516999165305257],
-
- v : [0.25,0.0,-0.9228444343424548],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-1.12 : {
- bb : {
- x : [0.7315236409857298,0.0,0.36906431245869276],
-
- v : [0.25,0.0,-1.020944434342455],
-
- x_b : [0.7337259166018127,0.0,0.0]}},
-
-1.13 : {
- bb : {
- x : [0.7338747787937718,0.0,0.025685855322728882],
-
- v : [0.125,0.0,0.5419981599338027],
-
- x_b : [0.7478360303826168,0.0,0.0]}},
-
-1.14 : {
- bb : {
- x : [0.7351247787937718,0.0,0.2197599340368246],
-
- v : [0.125,0.0,0.44389815993380266],
-
- x_b : [0.7478360303826168,0.0,0.0]}},
-
-1.15 : {
- bb : {
- x : [0.7363747787937718,0.0,0.3752119655068257],
-
- v : [0.125,0.0,0.3457981599338026],
-
- x_b : [0.7478360303826168,0.0,0.0]}},
-
-1.16 : {
- bb : {
- x : [0.7376247787937718,0.0,0.4920419497327323],
-
- v : [0.125,0.0,0.2476981599338025],
-
- x_b : [0.7478360303826168,0.0,0.0]}},
-
-1.17 : {
- bb : {
- x : [0.7388747787937717,0.0,0.5702498867145442],
-
- v : [0.125,0.0,0.14959815993380243],
-
- x_b : [0.7478360303826168,0.0,0.0]}},
-
-1.18 : {
- bb : {
- x : [0.7401247787937717,0.0,0.6098357764522617],
-
- v : [0.125,0.0,0.05149815993380234],
-
- x_b : [0.7478360303826168,0.0,0.0]}},
-
-1.19 : {
- bb : {
- x : [0.7413747787937717,0.0,0.6107996189458847],
-
- v : [0.125,0.0,-0.04660184006619775],
-
- x_b : [0.7478360303826168,0.0,0.0]}},
-
-1.2 : {
- bb : {
- x : [0.7426247787937716,0.0,0.5731414141954131],
-
- v : [0.125,0.0,-0.14470184006619785],
-
- x_b : [0.7478360303826168,0.0,0.0]}},
-
-1.21 : {
- bb : {
- x : [0.7438747787937716,0.0,0.496861162200847],
-
- v : [0.125,0.0,-0.24280184006619793],
-
- x_b : [0.7478360303826168,0.0,0.0]}},
-
-1.22 : {
- bb : {
- x : [0.7451247787937716,0.0,0.3819588629621863],
-
- v : [0.125,0.0,-0.340901840066198],
-
- x_b : [0.7478360303826168,0.0,0.0]}},
-
-1.23 : {
- bb : {
- x : [0.7463747787937716,0.0,0.22843451647943103],
-
- v : [0.125,0.0,-0.4390018400661981],
-
- x_b : [0.7478360303826168,0.0,0.0]}},
-
-1.24 : {
- bb : {
- x : [0.7476247787937715,0.0,0.036288122752581246],
-
- v : [0.125,0.0,-0.5371018400661982],
-
- x_b : [0.7478360303826168,0.0,0.0]}},
-
-1.25 : {
- bb : {
- x : [0.7483554045881944,0.0,0.07723706062656349],
-
- v : [0.0625,0.0,0.19531945707192871],
-
- x_b : [0.7513635588278178,0.0,0.0]}},
-
-1.26 : {
- bb : {
- x : [0.7489804045881944,0.0,0.1348234610485827],
-
- v : [0.0625,0.0,0.09721945707192862],
-
- x_b : [0.7513635588278178,0.0,0.0]}},
-
-1.27 : {
- bb : {
- x : [0.7496054045881944,0.0,0.15378781422650736],
-
- v : [0.0625,0.0,-0.000880542928071465],
-
- x_b : [0.7513635588278178,0.0,0.0]}},
-
-1.28 : {
- bb : {
- x : [0.7502304045881943,0.0,0.13413012016033746],
-
- v : [0.0625,0.0,-0.09898054292807155],
-
- x_b : [0.7513635588278178,0.0,0.0]}},
-
-1.29 : {
- bb : {
- x : [0.7508554045881943,0.0,0.07585037885007301],
-
- v : [0.0625,0.0,-0.19708054292807164],
-
- x_b : [0.7513635588278178,0.0,0.0]}},
-
-1.3 : {
- bb : {
- x : [0.751421981708006,0.0,0.009513280838386252],
-
- v : [0.03125,0.0,0.1200801056409922],
-
- x_b : [0.752245440939118,0.0,0.0]}},
-
-1.31 : {
- bb : {
- x : [0.751734481708006,0.0,0.03747788935846192],
-
- v : [0.03125,0.0,0.021980105640992106],
-
- x_b : [0.752245440939118,0.0,0.0]}},
-
-1.32 : {
- bb : {
- x : [0.7520469817080061,0.0,0.026820450634443035],
-
- v : [0.03125,0.0,-0.07611989435900798],
-
- x_b : [0.752245440939118,0.0,0.0]}},
-
-1.33 : {
- bb : {
- x : [0.752302461323562,0.0,0.007371921297349745],
-
- v : [0.015625,0.0,0.03341042992552368],
-
- x_b : [0.7524659114669431,0.0,0.0]}},
-
-1.34 : {
- bb : {
- x : [0.752458711323562,0.0,0.0012146102444062867],
-
- v : [0.015625,0.0,-0.06468957007447641],
-
- x_b : [0.7524659114669431,0.0,0.0]}},
-
-1.35 : {
- bb : {
- x : [0.752530732747076,0.0,0.0005005285453574175],
-
- v : [0.00390625,0.0,-0.007066826861079203],
-
- x_b : [0.7525348085068885,0.0,0.0]}},
-
-1.36 : {
- bb : {
- x : [0.7525394022900896,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.37 : {
- bb : {
- x : [0.7525394034821825,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.38 : {
- bb : {
- x : [0.7525394046742754,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.39 : {
- bb : {
- x : [0.7525394058663682,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.4 : {
- bb : {
- x : [0.7525394070584611,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.41 : {
- bb : {
- x : [0.752539408250554,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.42 : {
- bb : {
- x : [0.7525394094426469,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.43 : {
- bb : {
- x : [0.7525394106347397,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.44 : {
- bb : {
- x : [0.7525394118268326,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.45 : {
- bb : {
- x : [0.7525394130189255,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.46 : {
- bb : {
- x : [0.7525394142110183,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.47 : {
- bb : {
- x : [0.7525394154031112,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.48 : {
- bb : {
- x : [0.7525394165952041,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.49 : {
- bb : {
- x : [0.7525394177872969,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.5 : {
- bb : {
- x : [0.7525394189793898,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.51 : {
- bb : {
- x : [0.7525394201714827,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.52 : {
- bb : {
- x : [0.7525394213635755,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.53 : {
- bb : {
- x : [0.7525394225556684,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.54 : {
- bb : {
- x : [0.7525394237477613,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.55 : {
- bb : {
- x : [0.7525394249398542,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.56 : {
- bb : {
- x : [0.752539426131947,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.57 : {
- bb : {
- x : [0.7525394273240399,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.58 : {
- bb : {
- x : [0.7525394285161328,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.59 : {
- bb : {
- x : [0.7525394297082256,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.6 : {
- bb : {
- x : [0.7525394309003185,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.61 : {
- bb : {
- x : [0.7525394320924114,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.62 : {
- bb : {
- x : [0.7525394332845042,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.63 : {
- bb : {
- x : [0.7525394344765971,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.64 : {
- bb : {
- x : [0.75253943566869,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.65 : {
- bb : {
- x : [0.7525394368607828,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.66 : {
- bb : {
- x : [0.7525394380528757,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.67 : {
- bb : {
- x : [0.7525394392449686,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.68 : {
- bb : {
- x : [0.7525394404370614,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.69 : {
- bb : {
- x : [0.7525394416291543,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.7 : {
- bb : {
- x : [0.7525394428212472,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.71 : {
- bb : {
- x : [0.75253944401334,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.72 : {
- bb : {
- x : [0.7525394452054329,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.73 : {
- bb : {
- x : [0.7525394463975258,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.74 : {
- bb : {
- x : [0.7525394475896187,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.75 : {
- bb : {
- x : [0.7525394487817115,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.76 : {
- bb : {
- x : [0.7525394499738044,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.77 : {
- bb : {
- x : [0.7525394511658973,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.78 : {
- bb : {
- x : [0.7525394523579901,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.79 : {
- bb : {
- x : [0.752539453550083,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.8 : {
- bb : {
- x : [0.7525394547421759,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.81 : {
- bb : {
- x : [0.7525394559342687,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.82 : {
- bb : {
- x : [0.7525394571263616,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.83 : {
- bb : {
- x : [0.7525394583184545,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.84 : {
- bb : {
- x : [0.7525394595105473,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.85 : {
- bb : {
- x : [0.7525394607026402,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.86 : {
- bb : {
- x : [0.7525394618947331,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.87 : {
- bb : {
- x : [0.752539463086826,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.88 : {
- bb : {
- x : [0.7525394642789188,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.89 : {
- bb : {
- x : [0.7525394654710117,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.9 : {
- bb : {
- x : [0.7525394666631046,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.91 : {
- bb : {
- x : [0.7525394678551974,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.92 : {
- bb : {
- x : [0.7525394690472903,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.93 : {
- bb : {
- x : [0.7525394702393832,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.94 : {
- bb : {
- x : [0.752539471431476,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.95 : {
- bb : {
- x : [0.7525394726235689,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.96 : {
- bb : {
- x : [0.7525394738156618,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.97 : {
- bb : {
- x : [0.7525394750077546,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.98 : {
- bb : {
- x : [0.7525394761998475,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-1.99 : {
- bb : {
- x : [0.7525394773919404,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.0 : {
- bb : {
- x : [0.7525394785840333,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.01 : {
- bb : {
- x : [0.7525394797761261,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.02 : {
- bb : {
- x : [0.752539480968219,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.03 : {
- bb : {
- x : [0.7525394821603119,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.04 : {
- bb : {
- x : [0.7525394833524047,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.05 : {
- bb : {
- x : [0.7525394845444976,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.06 : {
- bb : {
- x : [0.7525394857365905,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.07 : {
- bb : {
- x : [0.7525394869286833,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.08 : {
- bb : {
- x : [0.7525394881207762,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.09 : {
- bb : {
- x : [0.7525394893128691,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.1 : {
- bb : {
- x : [0.7525394905049619,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.11 : {
- bb : {
- x : [0.7525394916970548,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.12 : {
- bb : {
- x : [0.7525394928891477,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.13 : {
- bb : {
- x : [0.7525394940812405,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.14 : {
- bb : {
- x : [0.7525394952733334,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.15 : {
- bb : {
- x : [0.7525394964654263,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.16 : {
- bb : {
- x : [0.7525394976575192,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.17 : {
- bb : {
- x : [0.752539498849612,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.18 : {
- bb : {
- x : [0.7525395000417049,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.19 : {
- bb : {
- x : [0.7525395012337978,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.2 : {
- bb : {
- x : [0.7525395024258906,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.21 : {
- bb : {
- x : [0.7525395036179835,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.22 : {
- bb : {
- x : [0.7525395048100764,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.23 : {
- bb : {
- x : [0.7525395060021692,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.24 : {
- bb : {
- x : [0.7525395071942621,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.25 : {
- bb : {
- x : [0.752539508386355,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.26 : {
- bb : {
- x : [0.7525395095784478,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.27 : {
- bb : {
- x : [0.7525395107705407,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.28 : {
- bb : {
- x : [0.7525395119626336,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.29 : {
- bb : {
- x : [0.7525395131547264,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.3 : {
- bb : {
- x : [0.7525395143468193,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.31 : {
- bb : {
- x : [0.7525395155389122,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.32 : {
- bb : {
- x : [0.752539516731005,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.33 : {
- bb : {
- x : [0.7525395179230979,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.34 : {
- bb : {
- x : [0.7525395191151908,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.35 : {
- bb : {
- x : [0.7525395203072837,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.36 : {
- bb : {
- x : [0.7525395214993765,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.37 : {
- bb : {
- x : [0.7525395226914694,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.38 : {
- bb : {
- x : [0.7525395238835623,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.39 : {
- bb : {
- x : [0.7525395250756551,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.4 : {
- bb : {
- x : [0.752539526267748,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.41 : {
- bb : {
- x : [0.7525395274598409,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.42 : {
- bb : {
- x : [0.7525395286519337,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.43 : {
- bb : {
- x : [0.7525395298440266,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.44 : {
- bb : {
- x : [0.7525395310361195,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.45 : {
- bb : {
- x : [0.7525395322282123,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.46 : {
- bb : {
- x : [0.7525395334203052,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.47 : {
- bb : {
- x : [0.7525395346123981,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.48 : {
- bb : {
- x : [0.752539535804491,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.49 : {
- bb : {
- x : [0.7525395369965838,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.5 : {
- bb : {
- x : [0.7525395381886767,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.51 : {
- bb : {
- x : [0.7525395393807696,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.52 : {
- bb : {
- x : [0.7525395405728624,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.53 : {
- bb : {
- x : [0.7525395417649553,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.54 : {
- bb : {
- x : [0.7525395429570482,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.55 : {
- bb : {
- x : [0.752539544149141,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.56 : {
- bb : {
- x : [0.7525395453412339,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.57 : {
- bb : {
- x : [0.7525395465333268,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.58 : {
- bb : {
- x : [0.7525395477254196,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.59 : {
- bb : {
- x : [0.7525395489175125,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.6 : {
- bb : {
- x : [0.7525395501096054,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.61 : {
- bb : {
- x : [0.7525395513016983,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.62 : {
- bb : {
- x : [0.7525395524937911,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.63 : {
- bb : {
- x : [0.752539553685884,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.64 : {
- bb : {
- x : [0.7525395548779769,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.65 : {
- bb : {
- x : [0.7525395560700697,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.66 : {
- bb : {
- x : [0.7525395572621626,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.67 : {
- bb : {
- x : [0.7525395584542555,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.68 : {
- bb : {
- x : [0.7525395596463483,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.69 : {
- bb : {
- x : [0.7525395608384412,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.7 : {
- bb : {
- x : [0.7525395620305341,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.71 : {
- bb : {
- x : [0.7525395632226269,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.72 : {
- bb : {
- x : [0.7525395644147198,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.73 : {
- bb : {
- x : [0.7525395656068127,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.74 : {
- bb : {
- x : [0.7525395667989055,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.75 : {
- bb : {
- x : [0.7525395679909984,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.76 : {
- bb : {
- x : [0.7525395691830913,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.77 : {
- bb : {
- x : [0.7525395703751842,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.78 : {
- bb : {
- x : [0.752539571567277,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.79 : {
- bb : {
- x : [0.7525395727593699,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.8 : {
- bb : {
- x : [0.7525395739514628,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.81 : {
- bb : {
- x : [0.7525395751435556,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.82 : {
- bb : {
- x : [0.7525395763356485,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.83 : {
- bb : {
- x : [0.7525395775277414,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.84 : {
- bb : {
- x : [0.7525395787198342,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.85 : {
- bb : {
- x : [0.7525395799119271,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.86 : {
- bb : {
- x : [0.75253958110402,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.87 : {
- bb : {
- x : [0.7525395822961128,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.88 : {
- bb : {
- x : [0.7525395834882057,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.89 : {
- bb : {
- x : [0.7525395846802986,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.9 : {
- bb : {
- x : [0.7525395858723914,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.91 : {
- bb : {
- x : [0.7525395870644843,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.92 : {
- bb : {
- x : [0.7525395882565772,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.93 : {
- bb : {
- x : [0.75253958944867,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.94 : {
- bb : {
- x : [0.7525395906407629,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.95 : {
- bb : {
- x : [0.7525395918328558,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.96 : {
- bb : {
- x : [0.7525395930249487,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.97 : {
- bb : {
- x : [0.7525395942170415,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.98 : {
- bb : {
- x : [0.7525395954091344,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-2.99 : {
- bb : {
- x : [0.7525395966012273,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}},
-
-3.0 : {
- bb : {
- x : [0.7525395977933201,0.0,0.0],
-
- v : [1.1920928955078125e-07,0.0,0.0],
-
- x_b : [1e+300,1e+300,0.0]}}}
+ header: {
+ case: 'restitution',
+ dateTime: '1924-01-14T00:00:00',
+ cases: 'BouncingBall3D',
+ file: 'BouncingBall3D.cases',
+ casesDate: '1924-01-13T00:00:00',
+ timeUnit: 'second',
+ timeFactor: 1000000000.0},
+ '0.01': {
+ bb: {
+ e: 0.5,
+ g: 9.81,
+ x: [0.01,0.0,39.35076771653544],
+ v: [1.0,0.0,-0.0981],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.02': {
+ bb: {
+ x: [0.02,0.0,39.292834645669295],
+ v: [1.0,0.0,-0.1962],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.03': {
+ bb: {
+ x: [0.03,0.0,39.196279527559064],
+ v: [1.0,0.0,-0.2943],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.04': {
+ bb: {
+ x: [0.04,0.0,39.061102362204736],
+ v: [1.0,0.0,-0.3924],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.05': {
+ bb: {
+ x: [0.05,0.0,38.88730314960631],
+ v: [1.0,0.0,-0.49050000000000005],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.06': {
+ bb: {
+ x: [0.06,0.0,38.67488188976379],
+ v: [1.0,0.0,-0.5886],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.07': {
+ bb: {
+ x: [0.07,0.0,38.42383858267718],
+ v: [1.0,0.0,-0.6867000000000001],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.08': {
+ bb: {
+ x: [0.08,0.0,38.13417322834646],
+ v: [1.0,0.0,-0.7848],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.09': {
+ bb: {
+ x: [0.09,0.0,37.80588582677166],
+ v: [1.0,0.0,-0.8829],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.1': {
+ bb: {
+ x: [0.1,0.0,37.43897637795276],
+ v: [1.0,0.0,-0.9810000000000001],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.11': {
+ bb: {
+ x: [0.11,0.0,37.03344488188977],
+ v: [1.0,0.0,-1.0791],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.12': {
+ bb: {
+ x: [0.12,0.0,36.58929133858268],
+ v: [1.0,0.0,-1.1771999999999998],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.13': {
+ bb: {
+ x: [0.13,0.0,36.106515748031505],
+ v: [1.0,0.0,-1.2752999999999999],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.14': {
+ bb: {
+ x: [0.14,0.0,35.58511811023623],
+ v: [1.0,0.0,-1.3734],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.15': {
+ bb: {
+ x: [0.15,0.0,35.02509842519686],
+ v: [1.0,0.0,-1.4714999999999998],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.16': {
+ bb: {
+ x: [0.16,0.0,34.4264566929134],
+ v: [1.0,0.0,-1.5695999999999999],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.17': {
+ bb: {
+ x: [0.17,0.0,33.78919291338584],
+ v: [1.0,0.0,-1.6677],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.18': {
+ bb: {
+ x: [0.18,0.0,33.113307086614185],
+ v: [1.0,0.0,-1.7657999999999998],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.19': {
+ bb: {
+ x: [0.19,0.0,32.39879921259844],
+ v: [1.0,0.0,-1.8639],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.2': {
+ bb: {
+ x: [0.2,0.0,31.645669291338592],
+ v: [1.0,0.0,-1.962],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.21': {
+ bb: {
+ x: [0.21,0.0,30.85391732283466],
+ v: [1.0,0.0,-2.0601],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.22': {
+ bb: {
+ x: [0.22,0.0,30.023543307086626],
+ v: [1.0,0.0,-2.1582],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.23': {
+ bb: {
+ x: [0.23,0.0,29.1545472440945],
+ v: [1.0,0.0,-2.2563],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.24': {
+ bb: {
+ x: [0.24,0.0,28.24692913385828],
+ v: [1.0,0.0,-2.3543999999999996],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.25': {
+ bb: {
+ x: [0.25,0.0,27.300688976377963],
+ v: [1.0,0.0,-2.4524999999999997],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.26': {
+ bb: {
+ x: [0.26,0.0,26.315826771653555],
+ v: [1.0,0.0,-2.5505999999999998],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.27': {
+ bb: {
+ x: [0.27,0.0,25.292342519685054],
+ v: [1.0,0.0,-2.6487],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.28': {
+ bb: {
+ x: [0.28,0.0,24.230236220472456],
+ v: [1.0,0.0,-2.7468],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.29': {
+ bb: {
+ x: [0.29,0.0,23.129507874015765],
+ v: [1.0,0.0,-2.8448999999999995],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.3': {
+ bb: {
+ x: [0.3,0.0,21.990157480314977],
+ v: [1.0,0.0,-2.9429999999999996],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.31': {
+ bb: {
+ x: [0.31,0.0,20.812185039370096],
+ v: [1.0,0.0,-3.0410999999999997],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.32': {
+ bb: {
+ x: [0.32,0.0,19.595590551181118],
+ v: [1.0,0.0,-3.1391999999999998],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.33': {
+ bb: {
+ x: [0.33,0.0,18.340374015748047],
+ v: [1.0,0.0,-3.2373],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.34': {
+ bb: {
+ x: [0.34,0.0,17.04653543307088],
+ v: [1.0,0.0,-3.3354],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.35': {
+ bb: {
+ x: [0.35,0.0,15.714074803149627],
+ v: [1.0,0.0,-3.4334999999999996],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.36': {
+ bb: {
+ x: [0.36,0.0,14.342992125984273],
+ v: [1.0,0.0,-3.5315999999999996],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.37': {
+ bb: {
+ x: [0.37,0.0,12.933287401574823],
+ v: [1.0,0.0,-3.6296999999999997],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.38': {
+ bb: {
+ x: [0.38,0.0,11.484960629921279],
+ v: [1.0,0.0,-3.7278],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.39': {
+ bb: {
+ x: [0.39,0.0,9.99801181102364],
+ v: [1.0,0.0,-3.8259],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.4': {
+ bb: {
+ x: [0.4,0.0,8.472440944881907],
+ v: [1.0,0.0,-3.924],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.41': {
+ bb: {
+ x: [0.41,0.0,6.908248031496088],
+ v: [1.0,0.0,-4.022099999999999],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.42': {
+ bb: {
+ x: [0.42,0.0,5.305433070866167],
+ v: [1.0,0.0,-4.1202],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.43': {
+ bb: {
+ x: [0.43,0.0,3.66399606299215],
+ v: [1.0,0.0,-4.2183],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.44': {
+ bb: {
+ x: [0.44,0.0,1.9839370078740388],
+ v: [1.0,0.0,-4.316400000000001],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.45': {
+ bb: {
+ x: [0.45,0.0,0.26525590551183287],
+ v: [1.0,0.0,-4.414500000000001],
+ x_b: [0.4515236409857309,0.0,0.0]}},
+ '0.46': {
+ bb: {
+ x: [0.45576182049286545,0.0,0.7252115538706296],
+ v: [0.5,0.0,2.1315703771050307],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.47': {
+ bb: {
+ x: [0.4607618204928654,0.0,1.545101466116701],
+ v: [0.5,0.0,2.033470377105031],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.48': {
+ bb: {
+ x: [0.4657618204928654,0.0,2.3263693311186824],
+ v: [0.5,0.0,1.935370377105031],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.49': {
+ bb: {
+ x: [0.4707618204928654,0.0,3.069015148876569],
+ v: [0.5,0.0,1.837270377105031],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.5': {
+ bb: {
+ x: [0.4757618204928654,0.0,3.7730389193903613],
+ v: [0.5,0.0,1.7391703771050309],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.51': {
+ bb: {
+ x: [0.4807618204928654,0.0,4.438440642660058],
+ v: [0.5,0.0,1.6410703771050308],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.52': {
+ bb: {
+ x: [0.4857618204928654,0.0,5.065220318685662],
+ v: [0.5,0.0,1.5429703771050307],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.53': {
+ bb: {
+ x: [0.49076182049286543,0.0,5.65337794746717],
+ v: [0.5,0.0,1.4448703771050306],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.54': {
+ bb: {
+ x: [0.49576182049286543,0.0,6.202913529004584],
+ v: [0.5,0.0,1.3467703771050306],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.55': {
+ bb: {
+ x: [0.5007618204928654,0.0,6.713827063297904],
+ v: [0.5,0.0,1.2486703771050305],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.56': {
+ bb: {
+ x: [0.5057618204928654,0.0,7.186118550347129],
+ v: [0.5,0.0,1.1505703771050304],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.57': {
+ bb: {
+ x: [0.5107618204928654,0.0,7.619787990152255],
+ v: [0.5,0.0,1.0524703771050314],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.58': {
+ bb: {
+ x: [0.5157618204928655,0.0,8.014835382713292],
+ v: [0.5,0.0,0.9543703771050314],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.59': {
+ bb: {
+ x: [0.5207618204928655,0.0,8.371260728030233],
+ v: [0.5,0.0,0.8562703771050313],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.6': {
+ bb: {
+ x: [0.5257618204928655,0.0,8.689064026103079],
+ v: [0.5,0.0,0.7581703771050312],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.61': {
+ bb: {
+ x: [0.5307618204928655,0.0,8.968245276931832],
+ v: [0.5,0.0,0.6600703771050311],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.62': {
+ bb: {
+ x: [0.5357618204928655,0.0,9.20880448051649],
+ v: [0.5,0.0,0.5619703771050311],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.63': {
+ bb: {
+ x: [0.5407618204928655,0.0,9.410741636857054],
+ v: [0.5,0.0,0.463870377105031],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.64': {
+ bb: {
+ x: [0.5457618204928655,0.0,9.574056745953524],
+ v: [0.5,0.0,0.3657703771050309],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.65': {
+ bb: {
+ x: [0.5507618204928655,0.0,9.698749807805898],
+ v: [0.5,0.0,0.26767037710503083],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.66': {
+ bb: {
+ x: [0.5557618204928655,0.0,9.784820822414177],
+ v: [0.5,0.0,0.16957037710503076],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.67': {
+ bb: {
+ x: [0.5607618204928655,0.0,9.832269789778362],
+ v: [0.5,0.0,0.07147037710503067],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.68': {
+ bb: {
+ x: [0.5657618204928655,0.0,9.841096709898453],
+ v: [0.5,0.0,-0.026629622894969424],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.69': {
+ bb: {
+ x: [0.5707618204928655,0.0,9.811301582774451],
+ v: [0.5,0.0,-0.12472962289496843],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.7': {
+ bb: {
+ x: [0.5757618204928655,0.0,9.742884408406352],
+ v: [0.5,0.0,-0.22282962289496852],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.71': {
+ bb: {
+ x: [0.5807618204928655,0.0,9.63584518679416],
+ v: [0.5,0.0,-0.3209296228949686],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.72': {
+ bb: {
+ x: [0.5857618204928655,0.0,9.490183917937873],
+ v: [0.5,0.0,-0.4190296228949687],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.73': {
+ bb: {
+ x: [0.5907618204928655,0.0,9.305900601837491],
+ v: [0.5,0.0,-0.5171296228949688],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.74': {
+ bb: {
+ x: [0.5957618204928655,0.0,9.082995238493016],
+ v: [0.5,0.0,-0.6152296228949689],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.75': {
+ bb: {
+ x: [0.6007618204928655,0.0,8.821467827904446],
+ v: [0.5,0.0,-0.7133296228949689],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.76': {
+ bb: {
+ x: [0.6057618204928655,0.0,8.52131837007178],
+ v: [0.5,0.0,-0.811429622894969],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.77': {
+ bb: {
+ x: [0.6107618204928655,0.0,8.18254686499502],
+ v: [0.5,0.0,-0.9095296228949691],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.78': {
+ bb: {
+ x: [0.6157618204928655,0.0,7.805153312674166],
+ v: [0.5,0.0,-1.0076296228949693],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.79': {
+ bb: {
+ x: [0.6207618204928655,0.0,7.389137713109217],
+ v: [0.5,0.0,-1.1057296228949693],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.8': {
+ bb: {
+ x: [0.6257618204928656,0.0,6.934500066300174],
+ v: [0.5,0.0,-1.2038296228949694],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.81': {
+ bb: {
+ x: [0.6307618204928656,0.0,6.441240372247036],
+ v: [0.5,0.0,-1.3019296228949695],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.82': {
+ bb: {
+ x: [0.6357618204928654,0.0,5.90935863094981],
+ v: [0.5,0.0,-1.4000296228949685],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.83': {
+ bb: {
+ x: [0.6407618204928655,0.0,5.338854842408484],
+ v: [0.5,0.0,-1.4981296228949685],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.84': {
+ bb: {
+ x: [0.6457618204928655,0.0,4.729729006623062],
+ v: [0.5,0.0,-1.5962296228949686],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.85': {
+ bb: {
+ x: [0.6507618204928655,0.0,4.081981123593547],
+ v: [0.5,0.0,-1.6943296228949687],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.86': {
+ bb: {
+ x: [0.6557618204928655,0.0,3.395611193319936],
+ v: [0.5,0.0,-1.7924296228949688],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.87': {
+ bb: {
+ x: [0.6607618204928655,0.0,2.6706192158022315],
+ v: [0.5,0.0,-1.8905296228949688],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.88': {
+ bb: {
+ x: [0.6657618204928655,0.0,1.9070051910404322],
+ v: [0.5,0.0,-1.988629622894969],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.89': {
+ bb: {
+ x: [0.6707618204928655,0.0,1.1047691190345383],
+ v: [0.5,0.0,-2.086729622894969],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.9': {
+ bb: {
+ x: [0.6757618204928655,0.0,0.26391099978454996],
+ v: [0.5,0.0,-2.184829622894969],
+ x_b: [0.6772854614785964,0.0,0.0]}},
+ '0.91': {
+ bb: {
+ x: [0.6790236409857309,0.0,0.29378207670733264],
+ v: [0.25,0.0,1.0391555656575457],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '0.92': {
+ bb: {
+ x: [0.6815236409857308,0.0,0.6835874175173903],
+ v: [0.25,0.0,0.9410555656575457],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '0.93': {
+ bb: {
+ x: [0.6840236409857308,0.0,1.0347707110833533],
+ v: [0.25,0.0,0.8429555656575456],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '0.94': {
+ bb: {
+ x: [0.6865236409857307,0.0,1.3473319574052187],
+ v: [0.25,0.0,0.7448555656575466],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '0.95': {
+ bb: {
+ x: [0.6890236409857307,0.0,1.6212711564829934],
+ v: [0.25,0.0,0.6467555656575465],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '0.96': {
+ bb: {
+ x: [0.6915236409857306,0.0,1.8565883083166732],
+ v: [0.25,0.0,0.5486555656575465],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '0.97': {
+ bb: {
+ x: [0.6940236409857305,0.0,2.0532834129062585],
+ v: [0.25,0.0,0.4505555656575464],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '0.98': {
+ bb: {
+ x: [0.6965236409857305,0.0,2.211356470251749],
+ v: [0.25,0.0,0.3524555656575463],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '0.99': {
+ bb: {
+ x: [0.6990236409857304,0.0,2.3308074803531453],
+ v: [0.25,0.0,0.25435556565754625],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '1.0': {
+ bb: {
+ x: [0.7015236409857304,0.0,2.411636443210447],
+ v: [0.25,0.0,0.15625556565754617],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '1.01': {
+ bb: {
+ x: [0.7040236409857303,0.0,2.4538433588236543],
+ v: [0.25,0.0,0.05815556565754608],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '1.02': {
+ bb: {
+ x: [0.7065236409857303,0.0,2.457428227192767],
+ v: [0.25,0.0,-0.03994443434245401],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '1.03': {
+ bb: {
+ x: [0.7090236409857302,0.0,2.422391048317785],
+ v: [0.25,0.0,-0.13804443434245411],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '1.04': {
+ bb: {
+ x: [0.7115236409857302,0.0,2.3487318221987086],
+ v: [0.25,0.0,-0.2361444343424542],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '1.05': {
+ bb: {
+ x: [0.7140236409857301,0.0,2.2364505488355375],
+ v: [0.25,0.0,-0.33424443434245427],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '1.06': {
+ bb: {
+ x: [0.7165236409857301,0.0,2.085547228228272],
+ v: [0.25,0.0,-0.43234443434245434],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '1.07': {
+ bb: {
+ x: [0.71902364098573,0.0,1.896021860376912],
+ v: [0.25,0.0,-0.5304444343424545],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '1.08': {
+ bb: {
+ x: [0.72152364098573,0.0,1.6678744452814571],
+ v: [0.25,0.0,-0.6285444343424545],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '1.09': {
+ bb: {
+ x: [0.7240236409857299,0.0,1.401104982941908],
+ v: [0.25,0.0,-0.7266444343424546],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '1.1': {
+ bb: {
+ x: [0.7265236409857299,0.0,1.095713473358264],
+ v: [0.25,0.0,-0.8247444343424547],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '1.11': {
+ bb: {
+ x: [0.7290236409857298,0.0,0.7516999165305257],
+ v: [0.25,0.0,-0.9228444343424548],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '1.12': {
+ bb: {
+ x: [0.7315236409857298,0.0,0.36906431245869276],
+ v: [0.25,0.0,-1.020944434342455],
+ x_b: [0.7337259166018127,0.0,0.0]}},
+ '1.13': {
+ bb: {
+ x: [0.7338747787937718,0.0,0.025685855322728882],
+ v: [0.125,0.0,0.5419981599338027],
+ x_b: [0.7478360303826168,0.0,0.0]}},
+ '1.14': {
+ bb: {
+ x: [0.7351247787937718,0.0,0.2197599340368246],
+ v: [0.125,0.0,0.44389815993380266],
+ x_b: [0.7478360303826168,0.0,0.0]}},
+ '1.15': {
+ bb: {
+ x: [0.7363747787937718,0.0,0.3752119655068257],
+ v: [0.125,0.0,0.3457981599338026],
+ x_b: [0.7478360303826168,0.0,0.0]}},
+ '1.16': {
+ bb: {
+ x: [0.7376247787937718,0.0,0.4920419497327323],
+ v: [0.125,0.0,0.2476981599338025],
+ x_b: [0.7478360303826168,0.0,0.0]}},
+ '1.17': {
+ bb: {
+ x: [0.7388747787937717,0.0,0.5702498867145442],
+ v: [0.125,0.0,0.14959815993380243],
+ x_b: [0.7478360303826168,0.0,0.0]}},
+ '1.18': {
+ bb: {
+ x: [0.7401247787937717,0.0,0.6098357764522617],
+ v: [0.125,0.0,0.05149815993380234],
+ x_b: [0.7478360303826168,0.0,0.0]}},
+ '1.19': {
+ bb: {
+ x: [0.7413747787937717,0.0,0.6107996189458847],
+ v: [0.125,0.0,-0.04660184006619775],
+ x_b: [0.7478360303826168,0.0,0.0]}},
+ '1.2': {
+ bb: {
+ x: [0.7426247787937716,0.0,0.5731414141954131],
+ v: [0.125,0.0,-0.14470184006619785],
+ x_b: [0.7478360303826168,0.0,0.0]}},
+ '1.21': {
+ bb: {
+ x: [0.7438747787937716,0.0,0.496861162200847],
+ v: [0.125,0.0,-0.24280184006619793],
+ x_b: [0.7478360303826168,0.0,0.0]}},
+ '1.22': {
+ bb: {
+ x: [0.7451247787937716,0.0,0.3819588629621863],
+ v: [0.125,0.0,-0.340901840066198],
+ x_b: [0.7478360303826168,0.0,0.0]}},
+ '1.23': {
+ bb: {
+ x: [0.7463747787937716,0.0,0.22843451647943103],
+ v: [0.125,0.0,-0.4390018400661981],
+ x_b: [0.7478360303826168,0.0,0.0]}},
+ '1.24': {
+ bb: {
+ x: [0.7476247787937715,0.0,0.036288122752581246],
+ v: [0.125,0.0,-0.5371018400661982],
+ x_b: [0.7478360303826168,0.0,0.0]}},
+ '1.25': {
+ bb: {
+ x: [0.7483554045881944,0.0,0.07723706062656349],
+ v: [0.0625,0.0,0.19531945707192871],
+ x_b: [0.7513635588278178,0.0,0.0]}},
+ '1.26': {
+ bb: {
+ x: [0.7489804045881944,0.0,0.1348234610485827],
+ v: [0.0625,0.0,0.09721945707192862],
+ x_b: [0.7513635588278178,0.0,0.0]}},
+ '1.27': {
+ bb: {
+ x: [0.7496054045881944,0.0,0.15378781422650736],
+ v: [0.0625,0.0,-0.000880542928071465],
+ x_b: [0.7513635588278178,0.0,0.0]}},
+ '1.28': {
+ bb: {
+ x: [0.7502304045881943,0.0,0.13413012016033746],
+ v: [0.0625,0.0,-0.09898054292807155],
+ x_b: [0.7513635588278178,0.0,0.0]}},
+ '1.29': {
+ bb: {
+ x: [0.7508554045881943,0.0,0.07585037885007301],
+ v: [0.0625,0.0,-0.19708054292807164],
+ x_b: [0.7513635588278178,0.0,0.0]}},
+ '1.3': {
+ bb: {
+ x: [0.751421981708006,0.0,0.009513280838386252],
+ v: [0.03125,0.0,0.1200801056409922],
+ x_b: [0.752245440939118,0.0,0.0]}},
+ '1.31': {
+ bb: {
+ x: [0.751734481708006,0.0,0.03747788935846192],
+ v: [0.03125,0.0,0.021980105640992106],
+ x_b: [0.752245440939118,0.0,0.0]}},
+ '1.32': {
+ bb: {
+ x: [0.7520469817080061,0.0,0.026820450634443035],
+ v: [0.03125,0.0,-0.07611989435900798],
+ x_b: [0.752245440939118,0.0,0.0]}},
+ '1.33': {
+ bb: {
+ x: [0.752302461323562,0.0,0.007371921297349745],
+ v: [0.015625,0.0,0.03341042992552368],
+ x_b: [0.7524659114669431,0.0,0.0]}},
+ '1.34': {
+ bb: {
+ x: [0.752458711323562,0.0,0.0012146102444062867],
+ v: [0.015625,0.0,-0.06468957007447641],
+ x_b: [0.7524659114669431,0.0,0.0]}},
+ '1.35': {
+ bb: {
+ x: [0.752530732747076,0.0,0.0005005285453574175],
+ v: [0.00390625,0.0,-0.007066826861079203],
+ x_b: [0.7525348085068885,0.0,0.0]}},
+ '1.36': {
+ bb: {
+ x: [0.7525394022900896,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.37': {
+ bb: {
+ x: [0.7525394034821825,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.38': {
+ bb: {
+ x: [0.7525394046742754,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.39': {
+ bb: {
+ x: [0.7525394058663682,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.4': {
+ bb: {
+ x: [0.7525394070584611,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.41': {
+ bb: {
+ x: [0.752539408250554,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.42': {
+ bb: {
+ x: [0.7525394094426469,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.43': {
+ bb: {
+ x: [0.7525394106347397,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.44': {
+ bb: {
+ x: [0.7525394118268326,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.45': {
+ bb: {
+ x: [0.7525394130189255,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.46': {
+ bb: {
+ x: [0.7525394142110183,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.47': {
+ bb: {
+ x: [0.7525394154031112,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.48': {
+ bb: {
+ x: [0.7525394165952041,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.49': {
+ bb: {
+ x: [0.7525394177872969,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.5': {
+ bb: {
+ x: [0.7525394189793898,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.51': {
+ bb: {
+ x: [0.7525394201714827,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.52': {
+ bb: {
+ x: [0.7525394213635755,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.53': {
+ bb: {
+ x: [0.7525394225556684,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.54': {
+ bb: {
+ x: [0.7525394237477613,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.55': {
+ bb: {
+ x: [0.7525394249398542,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.56': {
+ bb: {
+ x: [0.752539426131947,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.57': {
+ bb: {
+ x: [0.7525394273240399,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.58': {
+ bb: {
+ x: [0.7525394285161328,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.59': {
+ bb: {
+ x: [0.7525394297082256,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.6': {
+ bb: {
+ x: [0.7525394309003185,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.61': {
+ bb: {
+ x: [0.7525394320924114,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.62': {
+ bb: {
+ x: [0.7525394332845042,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.63': {
+ bb: {
+ x: [0.7525394344765971,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.64': {
+ bb: {
+ x: [0.75253943566869,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.65': {
+ bb: {
+ x: [0.7525394368607828,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.66': {
+ bb: {
+ x: [0.7525394380528757,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.67': {
+ bb: {
+ x: [0.7525394392449686,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.68': {
+ bb: {
+ x: [0.7525394404370614,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.69': {
+ bb: {
+ x: [0.7525394416291543,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.7': {
+ bb: {
+ x: [0.7525394428212472,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.71': {
+ bb: {
+ x: [0.75253944401334,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.72': {
+ bb: {
+ x: [0.7525394452054329,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.73': {
+ bb: {
+ x: [0.7525394463975258,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.74': {
+ bb: {
+ x: [0.7525394475896187,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.75': {
+ bb: {
+ x: [0.7525394487817115,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.76': {
+ bb: {
+ x: [0.7525394499738044,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.77': {
+ bb: {
+ x: [0.7525394511658973,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.78': {
+ bb: {
+ x: [0.7525394523579901,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.79': {
+ bb: {
+ x: [0.752539453550083,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.8': {
+ bb: {
+ x: [0.7525394547421759,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.81': {
+ bb: {
+ x: [0.7525394559342687,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.82': {
+ bb: {
+ x: [0.7525394571263616,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.83': {
+ bb: {
+ x: [0.7525394583184545,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.84': {
+ bb: {
+ x: [0.7525394595105473,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.85': {
+ bb: {
+ x: [0.7525394607026402,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.86': {
+ bb: {
+ x: [0.7525394618947331,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.87': {
+ bb: {
+ x: [0.752539463086826,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.88': {
+ bb: {
+ x: [0.7525394642789188,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.89': {
+ bb: {
+ x: [0.7525394654710117,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.9': {
+ bb: {
+ x: [0.7525394666631046,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.91': {
+ bb: {
+ x: [0.7525394678551974,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.92': {
+ bb: {
+ x: [0.7525394690472903,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.93': {
+ bb: {
+ x: [0.7525394702393832,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.94': {
+ bb: {
+ x: [0.752539471431476,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.95': {
+ bb: {
+ x: [0.7525394726235689,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.96': {
+ bb: {
+ x: [0.7525394738156618,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.97': {
+ bb: {
+ x: [0.7525394750077546,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.98': {
+ bb: {
+ x: [0.7525394761998475,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '1.99': {
+ bb: {
+ x: [0.7525394773919404,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.0': {
+ bb: {
+ x: [0.7525394785840333,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.01': {
+ bb: {
+ x: [0.7525394797761261,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.02': {
+ bb: {
+ x: [0.752539480968219,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.03': {
+ bb: {
+ x: [0.7525394821603119,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.04': {
+ bb: {
+ x: [0.7525394833524047,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.05': {
+ bb: {
+ x: [0.7525394845444976,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.06': {
+ bb: {
+ x: [0.7525394857365905,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.07': {
+ bb: {
+ x: [0.7525394869286833,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.08': {
+ bb: {
+ x: [0.7525394881207762,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.09': {
+ bb: {
+ x: [0.7525394893128691,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.1': {
+ bb: {
+ x: [0.7525394905049619,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.11': {
+ bb: {
+ x: [0.7525394916970548,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.12': {
+ bb: {
+ x: [0.7525394928891477,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.13': {
+ bb: {
+ x: [0.7525394940812405,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.14': {
+ bb: {
+ x: [0.7525394952733334,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.15': {
+ bb: {
+ x: [0.7525394964654263,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.16': {
+ bb: {
+ x: [0.7525394976575192,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.17': {
+ bb: {
+ x: [0.752539498849612,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.18': {
+ bb: {
+ x: [0.7525395000417049,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.19': {
+ bb: {
+ x: [0.7525395012337978,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.2': {
+ bb: {
+ x: [0.7525395024258906,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.21': {
+ bb: {
+ x: [0.7525395036179835,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.22': {
+ bb: {
+ x: [0.7525395048100764,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.23': {
+ bb: {
+ x: [0.7525395060021692,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.24': {
+ bb: {
+ x: [0.7525395071942621,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.25': {
+ bb: {
+ x: [0.752539508386355,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.26': {
+ bb: {
+ x: [0.7525395095784478,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.27': {
+ bb: {
+ x: [0.7525395107705407,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.28': {
+ bb: {
+ x: [0.7525395119626336,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.29': {
+ bb: {
+ x: [0.7525395131547264,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.3': {
+ bb: {
+ x: [0.7525395143468193,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.31': {
+ bb: {
+ x: [0.7525395155389122,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.32': {
+ bb: {
+ x: [0.752539516731005,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.33': {
+ bb: {
+ x: [0.7525395179230979,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.34': {
+ bb: {
+ x: [0.7525395191151908,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.35': {
+ bb: {
+ x: [0.7525395203072837,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.36': {
+ bb: {
+ x: [0.7525395214993765,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.37': {
+ bb: {
+ x: [0.7525395226914694,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.38': {
+ bb: {
+ x: [0.7525395238835623,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.39': {
+ bb: {
+ x: [0.7525395250756551,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.4': {
+ bb: {
+ x: [0.752539526267748,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.41': {
+ bb: {
+ x: [0.7525395274598409,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.42': {
+ bb: {
+ x: [0.7525395286519337,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.43': {
+ bb: {
+ x: [0.7525395298440266,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.44': {
+ bb: {
+ x: [0.7525395310361195,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.45': {
+ bb: {
+ x: [0.7525395322282123,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.46': {
+ bb: {
+ x: [0.7525395334203052,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.47': {
+ bb: {
+ x: [0.7525395346123981,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.48': {
+ bb: {
+ x: [0.752539535804491,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.49': {
+ bb: {
+ x: [0.7525395369965838,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.5': {
+ bb: {
+ x: [0.7525395381886767,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.51': {
+ bb: {
+ x: [0.7525395393807696,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.52': {
+ bb: {
+ x: [0.7525395405728624,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.53': {
+ bb: {
+ x: [0.7525395417649553,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.54': {
+ bb: {
+ x: [0.7525395429570482,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.55': {
+ bb: {
+ x: [0.752539544149141,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.56': {
+ bb: {
+ x: [0.7525395453412339,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.57': {
+ bb: {
+ x: [0.7525395465333268,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.58': {
+ bb: {
+ x: [0.7525395477254196,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.59': {
+ bb: {
+ x: [0.7525395489175125,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.6': {
+ bb: {
+ x: [0.7525395501096054,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.61': {
+ bb: {
+ x: [0.7525395513016983,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.62': {
+ bb: {
+ x: [0.7525395524937911,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.63': {
+ bb: {
+ x: [0.752539553685884,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.64': {
+ bb: {
+ x: [0.7525395548779769,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.65': {
+ bb: {
+ x: [0.7525395560700697,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.66': {
+ bb: {
+ x: [0.7525395572621626,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.67': {
+ bb: {
+ x: [0.7525395584542555,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.68': {
+ bb: {
+ x: [0.7525395596463483,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.69': {
+ bb: {
+ x: [0.7525395608384412,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.7': {
+ bb: {
+ x: [0.7525395620305341,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.71': {
+ bb: {
+ x: [0.7525395632226269,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.72': {
+ bb: {
+ x: [0.7525395644147198,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.73': {
+ bb: {
+ x: [0.7525395656068127,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.74': {
+ bb: {
+ x: [0.7525395667989055,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.75': {
+ bb: {
+ x: [0.7525395679909984,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.76': {
+ bb: {
+ x: [0.7525395691830913,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.77': {
+ bb: {
+ x: [0.7525395703751842,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.78': {
+ bb: {
+ x: [0.752539571567277,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.79': {
+ bb: {
+ x: [0.7525395727593699,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.8': {
+ bb: {
+ x: [0.7525395739514628,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.81': {
+ bb: {
+ x: [0.7525395751435556,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.82': {
+ bb: {
+ x: [0.7525395763356485,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.83': {
+ bb: {
+ x: [0.7525395775277414,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.84': {
+ bb: {
+ x: [0.7525395787198342,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.85': {
+ bb: {
+ x: [0.7525395799119271,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.86': {
+ bb: {
+ x: [0.75253958110402,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.87': {
+ bb: {
+ x: [0.7525395822961128,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.88': {
+ bb: {
+ x: [0.7525395834882057,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.89': {
+ bb: {
+ x: [0.7525395846802986,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.9': {
+ bb: {
+ x: [0.7525395858723914,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.91': {
+ bb: {
+ x: [0.7525395870644843,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.92': {
+ bb: {
+ x: [0.7525395882565772,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.93': {
+ bb: {
+ x: [0.75253958944867,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.94': {
+ bb: {
+ x: [0.7525395906407629,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.95': {
+ bb: {
+ x: [0.7525395918328558,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.96': {
+ bb: {
+ x: [0.7525395930249487,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.97': {
+ bb: {
+ x: [0.7525395942170415,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.98': {
+ bb: {
+ x: [0.7525395954091344,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '2.99': {
+ bb: {
+ x: [0.7525395966012273,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}},
+ '3.0': {
+ bb: {
+ x: [0.7525395977933201,0.0,0.0],
+ v: [0.00000011920928955078125,0.0,0.0],
+ x_b: [1e+300,1e+300,0.0]}}}
\ No newline at end of file
diff --git a/tests/data/MobileCrane/MobileCrane.cases b/tests/data/MobileCrane/MobileCrane.cases
index 0a433b7..6a3e71a 100644
--- a/tests/data/MobileCrane/MobileCrane.cases
+++ b/tests/data/MobileCrane/MobileCrane.cases
@@ -1,64 +1,69 @@
-{header : {
- name : 'MobileCrane',
- description : 'sim explorer with the MobileCrane FMU (standalone)',
- modelFile : "OspSystemStructure.xml",
- simulator : "OSP",
- logLevel : 'trace', # possible levels: trace, debug, info, warning, error, fatal
- timeUnit : "second",
- variables : {
- p : ['mobileCrane', 'pedestal_boom', "Length and angle of pedestal. Use p[2] to set pedestal azimuth [degrees]"],
- b : ['mobileCrane', 'boom_boom', "Length and angle of boom. Use b[1] to set boom polar angle [degrees]"],
- r : ['mobileCrane', 'rope_boom', "Length and angle of rope. Use r[0] to set rope length [m]"],
- df_dt : ['mobileCrane', 'fixation_angularVelocity', "Angular velocity of whole crane with respect to base. [polar/time, azimuth/time]"],
- dp_dt : ['mobileCrane', 'pedestal_angularVelocity[1]', "Angular velocity of pedestal (around z-axis). [azimuth/time]"],
- db_dt : ['mobileCrane', 'boom_angularVelocity[0]', "Angular velocity of boom (polar direction). [polar/time]"],
- dr_dt : ['mobileCrane', 'rope_lengthVelocity', "Linear length change of crane rope. [m/s]"],
- v : ['mobileCrane', 'fixation_angularVelocity', "Linear velocity of whole crane with respect to base. [|v|, normal]"],
- T : ['mobileCrane', 'fixation_torque', "Total torque of the crane with respect to its base, i.e. the sum of static and dynamic torques. Provided as 3D spherical vector."],
- x_pedestal : ['mobileCrane', 'pedestal_end', "Cartesian coordinate of pedestal tip"],
- x_boom : ['mobileCrane', 'boom_end', "Cartesian coordinate of booom tip"],
- x_load : ['mobileCrane', 'rope_end', "Cartesian coordinate of rope tip (load position)"],
- load : ['mobileCrane', 'dLoad', "Rope mass (load) [kg]"],
- }},
-base : {
- description : "Variable settings for the base case. Represents a mobile crane folded for street use.",
- spec: {
- stopTime : 1.0,
- stepSize : 0.1,
- p[0,2] : [3.0, 0.0],
- b[0,1] : [8.0, 90], #1.570796], # 90 deg polar (horizontal)
- r[0] : 1e-6, # very short rope
- df_dt : [0.0, 0.0],
- dp_dt : 0.0,
- db_dt : 0.0,
- dr_dt : 0.0,
- v : [0.0, 0.0],
- load : 50.0,
- },
- results : [
- T@step,
- x_pedestal@step,
- x_boom@step,
- x_load@step,
- ]},
-static : {
- description : "Static end position. Represents a mobile crane during lifting (turned 90deg, boom lifted 45 deg, load lifted 1 m)",
- spec: {
- p[2] : 1.570796, # 90 deg azimuth (turned in y-direction)
- b[1] : 45, #0.785398, # 45 deg polar (turned 45 deg up)
- r[0] : 7.657, # length of rope such that load 1m over floor
- load : 1000, # load weight in kg
- }},
-dynamic : {
- description : "Movement to end position. Represents a mobile crane during lifting (turned 90deg, boom lifted 45 deg, load lifted 1 m)",
- spec: {
- stopTime : 1.1,
- dp_dt : 1.570796, #'90 deg/sec'
- db_dt : 0.785498, #'45 deg/sec'
- dr_dt : 7.657, # prolong to keep at 'floor'
- dp_dt@1.0 : 0.0,
- db_dt@1.0 : 0.0,
- dr_dt@1.0 : -10, # lift 1m / 0.1sec
- load@1.0 : 1000,
- }},
+{
+ header : {
+ name : 'MobileCrane',
+ description : 'sim explorer with the MobileCrane FMU (standalone)',
+ modelFile : "OspSystemStructure.xml",
+ simulator : "OSP",
+ logLevel : 'trace', # possible levels: trace, debug, info, warning, error, fatal
+ timeUnit : "second",
+ variables : {
+ p : ['mobileCrane', 'pedestal.boom', "Length and angle of pedestal. Use p[2] to set pedestal azimuth [degrees]"],
+ b : ['mobileCrane', 'boom.boom', "Length and angle of boom. Use b[1] to set boom polar angle [degrees]"],
+ r : ['mobileCrane', 'wire.boom', "Length and angle of wire fixed to the last boom. Use r[0] to set wire length [m]"],
+ df_dt : ['mobileCrane', 'd_angular', "Angular velocity of whole crane with respect to base. [polar/time, azimuth/time]"],
+ dp_dt : ['mobileCrane', 'der(pedestal.boom[2])', "Angular velocity of pedestal (around z-axis). [azimuth/time]"],
+ db_dt : ['mobileCrane', 'der(boom.boom[1])', "Angular velocity of boom (polar direction). [polar/time]"],
+ dr_dt : ['mobileCrane', 'der(wire.boom[0])', "Linear length change of crane wire. [m/s]"],
+ v : ['mobileCrane', 'velocity', "Linear velocity of whole crane with respect to base. [|v|, normal]"],
+ T : ['mobileCrane', 'torque', "Total torque of the crane with respect to its base, i.e. the sum of static and dynamic torques. Provided as 3D spherical vector."],
+ x_pedestal : ['mobileCrane', 'pedestal.end', "Cartesian coordinate of pedestal tip"],
+ x_boom : ['mobileCrane', 'boom.end', "Cartesian coordinate of booom tip"],
+ x_load : ['mobileCrane', 'wire.end', "Cartesian coordinate of wire tip (load position)"],
+ load : ['mobileCrane', 'wire.mass', "Wire mass (load) [kg]"],
+ },
+ },
+ base : {
+ description : "Variable settings for the base case. Represents a mobile crane folded for street use.",
+ spec: {
+ stopTime : 1.0,
+ stepSize : 0.1,
+ "p[0,2]" : [3.0, 0.0],
+ "b[0,1]" : [8.0, 90], #1.570796], # 90 deg polar (horizontal)
+ "r[0]" : 1e-6, # very short wire
+ df_dt : [0.0, 0.0, 0.0],
+ dp_dt : 0.0,
+ db_dt : 0.0,
+ dr_dt : 0.0,
+ v : [0.0, 0.0, 0.0],
+ load : 50.0,
+ },
+ results : [
+ "T@step",
+ "x_pedestal@step",
+ "x_boom@step",
+ "x_load@step",
+ ],
+ },
+ static : {
+ description : "Static end position. Represents a mobile crane during lifting (turned 90deg, boom lifted 45 deg, load lifted 1 m)",
+ spec: {
+ "p[2]" : 1.570796, # 90 deg azimuth (turned in y-direction)
+ "b[1]" : 45, #0.785398, # 45 deg polar (turned 45 deg up)
+ "r[0]" : 7.657, # length of wire such that load 1m over floor
+ load : 1000, # load weight in kg
+ },
+ },
+ dynamic : {
+ description : "Movement to end position. Represents a mobile crane during lifting (turned 90deg, boom lifted 45 deg, load lifted 1 m)",
+ spec: {
+ stopTime : 1.1,
+ dp_dt : 1.570796, #'90 deg/sec'
+ db_dt : 0.785498, #'45 deg/sec'
+ dr_dt : 7.657, # prolong to keep at 'floor'
+ "dp_dt@1.0" : 0.0,
+ "db_dt@1.0" : 0.0,
+ "dr_dt@1.0" : -10, # lift 1m / 0.1sec
+ "load@1.0" : 1000,
+ },
+ },
}
diff --git a/tests/data/MobileCrane/MobileCrane.fmu b/tests/data/MobileCrane/MobileCrane.fmu
index 482b5b1..c455a21 100644
Binary files a/tests/data/MobileCrane/MobileCrane.fmu and b/tests/data/MobileCrane/MobileCrane.fmu differ
diff --git a/tests/data/MobileCrane/OspSystemStructure.xml b/tests/data/MobileCrane/OspSystemStructure.xml
index c31bdaf..dd2d653 100644
--- a/tests/data/MobileCrane/OspSystemStructure.xml
+++ b/tests/data/MobileCrane/OspSystemStructure.xml
@@ -1,6 +1,8 @@
-
-
-
-
-
\ No newline at end of file
+ 0.0
+ 0.01
+ fixedStep
+
+
+
+
diff --git a/tests/data/MobileCrane/crane_table.js5 b/tests/data/MobileCrane/crane_table.js5
index 57ed315..5823fc5 100644
--- a/tests/data/MobileCrane/crane_table.js5
+++ b/tests/data/MobileCrane/crane_table.js5
@@ -1,17 +1,22 @@
{
-header : {
- xmlns : "http://opensimulationplatform.com/MSMI/OSPSystemStructure",
- version : "0.1",
- StartTime : 0.0,
- Algorithm : "fixedStep",
- BaseStepSize : 0.01,
- },
-Simulators : {
- simpleTable : {source: "../SimpleTable/SimpleTable.fmu", interpolate: True},
- mobileCrane : {source: "MobileCrane.fmu" stepSize: 0.01,
- pedestal.pedestalMass: 5000.0, boom.boom[0]: 20.0},
- },
-ConnectionsVariable : [
- ["simpleTable", "outputs[0]", "mobileCrane", "pedestal.angularVelocity"],
- ],
-}
\ No newline at end of file
+ header: {
+ xmlns: 'http://opensimulationplatform.com/MSMI/OSPSystemStructure',
+ version: '0.1',
+ StartTime: 0.0,
+ Algorithm: 'fixedStep',
+ BaseStepSize: 0.01,
+ },
+ Simulators: {
+ timeTable: {
+ source: '../TimeTable/TimeTableFMU.fmu',
+ interpolate: true,
+ },
+ mobileCrane: {
+ source: 'MobileCrane.fmu',
+ stepSize: 0.01,
+ 'pedestal.pedestalMass': 5000.0,
+ 'boom.boom[0]': 20.0,
+ },
+ },
+ ConnectionsVariable: [['timeTable','outputs[0]','mobileCrane','pedestal.angularVelocity']],
+}
diff --git a/tests/data/MobileCrane/crane_table.xml b/tests/data/MobileCrane/crane_table.xml
index e9d2ddd..678ba01 100644
--- a/tests/data/MobileCrane/crane_table.xml
+++ b/tests/data/MobileCrane/crane_table.xml
@@ -1,30 +1,31 @@
- 0.0
- 0.01
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ 0.0
+ 0.01
+ fixedStep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/data/MobileCrane/mobile_crane.py b/tests/data/MobileCrane/mobile_crane.py
index a21c60c..21f0b9c 100644
--- a/tests/data/MobileCrane/mobile_crane.py
+++ b/tests/data/MobileCrane/mobile_crane.py
@@ -1,9 +1,11 @@
-from crane_fmu.crane import Crane # , Animation
+from typing import Any
+from py_crane.crane_fmu import CraneFMU
-class MobileCrane(Crane):
+
+class MobileCrane(CraneFMU):
"""Simple mobile crane for FMU testing purposes.
- The crane has a short pedestal, one variable-length stiff boom and a rope.
+ The crane has a short pedestal, one variable-length stiff boom and a wire.
The size and weight of the various parts can be configured.
Args:
@@ -21,56 +23,55 @@ class MobileCrane(Crane):
def __init__(
self,
name: str = "mobile_crane",
- description: str = "Simple mobile crane (for FMU testing) with short pedestal, one variable-length elevation boom and a rope",
+ description: str = "Simple mobile crane (for FMU testing) with short pedestal, one variable-length elevation boom and a wire",
author: str = "DNV, SEACo project",
- version: str = "0.2",
+ version: str = "0.3",
+ degrees: bool = True,
pedestalMass: str = "10000.0 kg",
+ pedestalCoM: tuple[float, float, float] = (0.5, -1.0, 0.8),
pedestalHeight: str = "3.0 m",
boomMass: str = "1000.0 kg",
boomLength0: str = "8 m",
boomLength1: str = "50 m",
- rope_mass_range: tuple = ("50kg", "2000 kg"),
- **kwargs,
+ boomAngle: str = "90deg",
+ wire_mass_range: tuple[str, str] = ("50kg", "2000 kg"),
+ wire_mass: str | None = None,
+ wire_length: float = 0.1,
+ **kwargs: Any,
):
- super().__init__(
- name=name, description=description, author=author, version=version, **kwargs
- )
- _ = self.add_boom(
- name="pedestal",
+ super().__init__(name=name, description=description, author=author, version=version, degrees=degrees, **kwargs)
+ _pedestal = self.add_boom(
+ "pedestal",
description="The crane base, on one side fixed to the vessel and on the other side the first crane boom is fixed to it. The mass should include all additional items fixed to it, like the operator's cab",
mass=pedestalMass,
- massCenter=(0.5, -1.0, 0.8),
+ mass_center=pedestalCoM,
boom=(pedestalHeight, "0deg", "0deg"),
- boom_rng=(None, None, ("0deg", "360deg")),
+ boom_rng=(None, None, ()),
)
- _ = self.add_boom(
- name="boom",
+ _boom = self.add_boom(
+ "boom",
description="The boom. Can be lifted and length can change within the given range",
mass=boomMass,
- massCenter=(0.5, 0, 0),
- boom=(boomLength0, "90deg", "0deg"),
- boom_rng=((boomLength0, boomLength1), (0, "90deg"), None),
+ mass_center=(0.5, 0, 0),
+ boom=(boomLength0, boomAngle, "0deg"),
+ boom_rng=((boomLength0, boomLength1), (), None),
)
_ = self.add_boom(
- name="rope",
- description="The rope fixed to the last boom. Flexible connection",
- mass="50.0 kg", # so far basically the hook
- massCenter=0.95,
- mass_rng=rope_mass_range,
- boom=("1e-6 m", "180deg", "0 deg"),
- boom_rng=(
- ("1e-6 m", boomLength1),
- ("90deg", "270deg"),
- ("-180deg", "180deg"),
- ),
- damping=50.0,
- animationLW=2,
+ "wire",
+ description="The wire fixed to the last boom. Flexible connection",
+ mass=wire_mass_range[0] if wire_mass is None else wire_mass,
+ mass_center=0.99,
+ mass_rng=wire_mass_range,
+ boom=(f"{wire_length}m", "90deg", "0 deg"),
+ boom_rng=((f"{wire_length}m", boomLength1), (), ()),
+ q_factor=50.0,
+ additional_checks=True,
)
+
# make sure that _comSub is calculated for all booms:
self.calc_statics_dynamics(None)
- def do_step(self, currentTime, stepSize):
- status = super().do_step(currentTime, stepSize)
- # print(f"Time {currentTime}, {self.rope_tip}")
- # print(f"MobileCrane.do_step. Status {status}")
+ def do_step(self, current_time: float, step_size: float):
+ status = super().do_step(current_time, step_size)
+ # print(f"Time {current_time}, {self.force}, {self.torque}, {self.booms('wire').end}")
return status
diff --git a/tests/data/Oscillator/ForcedOscillator.cases b/tests/data/Oscillator/ForcedOscillator.cases
index 094703c..81c41c3 100644
--- a/tests/data/Oscillator/ForcedOscillator.cases
+++ b/tests/data/Oscillator/ForcedOscillator.cases
@@ -1,44 +1,36 @@
-{header : {
- name : 'ForcedOscillator',
- description : 'Test forced oscillator in various conditions',
- modelFile : "ForcedOscillator.xml",
- simulator : "OSP"
- logLevel : 'fatal', # possible levels: trace, debug, info, warning, error, fatal
- timeUnit : "second", # possible units: ns, us, ms, sec, min, h, d, or extensions of that, like 'second'
- variables : {
- k : ['osc', 'k', "The spring constant in N/m"],
- c : ['osc', 'c', "The damping constant N.s/m"],
- m : ['osc', 'm', "The mass connected to the system in kg. The spring mass is assumed negligible."],
- x_z : ['osc', 'x[2]', "Output connector for the 3D position of the mass in m (z-direction)"],
- v_z : ['osc', 'v[2]', "Output connector for the 3D speed of the mass in m/s (z-direction)"],
- A : ['drv', 'ampl', "The amplitude of the force in N"],
- f : ['drv', 'freq', "The frequency of the force in 1/s"],
- }},
-base: {
- description : "All basic initial settings and results specifications",
- spec: {
- stepSize : 0.01,
- stopTime : 10.0,
- k : 1.0,
- c : 0.5,
- m : 1.0,
- x_z : 1.0,
- v_z : 0.0,
- A : 1.0,
- f : 1.0,
- x_z@step : 'res',
- },
- assert: {
- 1@Always : ['k==1.0', 'Check setting'],
- }
- },
-no_damping_no_force: {
- spec: {
- c : 1E-7, #0.0,
- A : 0.0,
- }},
-resonant: {
- spec: {
- f : 0.15915,
- }},
-}
+{
+ header: {
+ name: 'ForcedOscillator',
+ description: 'Test forced oscillator in various conditions',
+ modelFile: 'OspSystemStructure.xml',
+ simulator: 'OSP',
+ logLevel: 'fatal',
+ timeUnit: 'second',
+ variables: {
+ k: ['osc','k','The spring constant in N/m'],
+ c: ['osc','c','The damping constant N.s/m'],
+ m: ['osc','m','The mass connected to the system in kg. The spring mass is assumed negligible.'],
+ x_z: ['osc','x[2]','Output connector for the 3D position of the mass in m (z-direction)'],
+ v_z: ['osc','v[2]','Output connector for the 3D speed of the mass in m/s (z-direction)'],
+ A: ['drv','ampl','The amplitude of the force in N'],
+ f: ['drv','freq','The frequency of the force in 1/s']}},
+ base: {
+ description: 'All basic initial settings and results specifications',
+ spec: {
+ stepSize: 0.01,
+ stopTime: 10.0,
+ k: 1.0,
+ c: 0.5,
+ m: 1.0,
+ x_z: 1.0,
+ v_z: 0.0,
+ A: 1.0,
+ f: 1.0,
+ 'x_z@step': 'res'}},
+ no_damping_no_force: {
+ spec: {
+ c: 0.0000001,
+ A: 0.0}},
+ resonant: {
+ spec: {
+ f: 0.15915}}}
diff --git a/tests/data/Oscillator/ForcedOscillator.xml b/tests/data/Oscillator/ForcedOscillator.xml
deleted file mode 100644
index 79b6700..0000000
--- a/tests/data/Oscillator/ForcedOscillator.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
- 0.0
- 0.01
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/tests/data/Oscillator/HarmonicOscillator.fmu b/tests/data/Oscillator/HarmonicOscillator.fmu
index e2807f9..feef548 100644
Binary files a/tests/data/Oscillator/HarmonicOscillator.fmu and b/tests/data/Oscillator/HarmonicOscillator.fmu differ
diff --git a/tests/data/Oscillator/OspSystemStructure.xml b/tests/data/Oscillator/OspSystemStructure.xml
new file mode 100644
index 0000000..e5c6123
--- /dev/null
+++ b/tests/data/Oscillator/OspSystemStructure.xml
@@ -0,0 +1,16 @@
+
+ 0.0
+ 0.01
+ fixedStep
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/data/Oscillator/oscillator_fmu.py b/tests/data/Oscillator/oscillator_fmu.py
index ddd74c5..2558c25 100644
--- a/tests/data/Oscillator/oscillator_fmu.py
+++ b/tests/data/Oscillator/oscillator_fmu.py
@@ -31,16 +31,16 @@ def __init__(self, k: float = 1.0, c: float = 0.0, m: float = 1.0, **kwargs: Any
self.f = np.array( (0,0,0), float)
self._interface(k, c, m)
- def do_step(self, time: float, dt: float):
+ def do_step(self, current_time: float, step_size: float):
"""Do one simulation step of size dt.
We implement a very simplistic algoritm based on difference calculus.
"""
- if not super().do_step(time, dt): # needed for FMU mechanism
+ if not super().do_step(current_time, step_size): # needed for FMU mechanism
return False
a = (self.f - self.k * self.x - self.c * self.v) / self.m
- self.x += self.v * dt # + a* dt*dt
- self.v += a * dt
+ self.x += self.v * step_size # + a* dt*dt
+ self.v += a * step_size
# print(f"@{time}: x={self.x}, v={self.v}, f={self.f}, a={a}")
return True # very important!
diff --git a/tests/data/SimpleTable/OspSystemStructure.xml b/tests/data/SimpleTable/OspSystemStructure.xml
deleted file mode 100644
index 8e4f091..0000000
--- a/tests/data/SimpleTable/OspSystemStructure.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/tests/data/SimpleTable/SimpleTable.fmu b/tests/data/SimpleTable/SimpleTable.fmu
deleted file mode 100644
index e23a625..0000000
Binary files a/tests/data/SimpleTable/SimpleTable.fmu and /dev/null differ
diff --git a/tests/data/SimpleTable/test.cases b/tests/data/SimpleTable/test.cases
deleted file mode 100644
index bbfb350..0000000
--- a/tests/data/SimpleTable/test.cases
+++ /dev/null
@@ -1,33 +0,0 @@
-{
-header : {
- name : 'Testing',
- description : 'Simple sim explorer for testing purposes',
- logLevel : 'info',
- simulator : 'OSP'
- timeUnit : 'second',
- variables : {
- x : ['tab','outs','Outputs (3-dim)'],
- i : ['tab','interpolate','Interpolation setting']}},
-
-base : {
- description : 'Mandatory base settings. No interpolation',
- spec : {
- stepSize : 0.1,
- stopTime : 1,
- i : False,
- },
- results : ['x@step',
- 'x[0]@1.0',
- 'i@0']
- },
-case1 : {
- description : 'Interpolation ON',
- spec : {
- i : True}},
-
-caseX : {
- description : 'Based case1 longer simulation',
- parent : 'case1',
- spec : {
- stopTime : 10}},
-}
diff --git a/tests/data/TimeTable/OspSystemStructure.xml b/tests/data/TimeTable/OspSystemStructure.xml
new file mode 100644
index 0000000..00cfe87
--- /dev/null
+++ b/tests/data/TimeTable/OspSystemStructure.xml
@@ -0,0 +1,11 @@
+
+
+ 0.0
+ 0.01
+ fixedStep
+
+
+
+
+
+
diff --git a/tests/data/TimeTable/TimeTableFMU.fmu b/tests/data/TimeTable/TimeTableFMU.fmu
new file mode 100644
index 0000000..af4c9f6
Binary files /dev/null and b/tests/data/TimeTable/TimeTableFMU.fmu differ
diff --git a/tests/data/TimeTable/test.cases b/tests/data/TimeTable/test.cases
new file mode 100644
index 0000000..a35e6a0
--- /dev/null
+++ b/tests/data/TimeTable/test.cases
@@ -0,0 +1,41 @@
+{
+ header : {
+ name : 'Testing',
+ description : 'Simple sim explorer for testing purposes',
+ logLevel : 'info',
+ simulator : 'OSP',
+ timeUnit : 'second',
+ variables : {
+ i : ['tab','interpolate','Interpolation setting'],
+ x : ['tab','outs','Outputs (3-dim)'],
+ },
+ },
+
+ base : {
+ description : 'Mandatory base settings. No interpolation',
+ spec : {
+ stepSize : 0.1,
+ stopTime : 1,
+ i : false,
+ },
+ results : [
+ 'x@step',
+ 'x[0]@1.0',
+ 'i@0',
+ ],
+ },
+ case1 : {
+ description : 'Interpolation ON',
+ spec : {
+ i : true
+ },
+ },
+
+ caseX : {
+ description : 'Based case1 longer simulation',
+ parent : 'case1',
+ spec : {
+ stopTime : 10,
+ },
+ },
+}
diff --git a/tests/data/template.cases b/tests/data/template.cases
index 7cf138d..7dc6df3 100644
--- a/tests/data/template.cases
+++ b/tests/data/template.cases
@@ -1,24 +1,19 @@
-{header : {
- name : '',
- description : 'Simulation-exploration-description>',
- modelFile : "OspSystemStructure.xml", # this will often be ok
- simulator : "OSP"
- logLevel : 'fatal', # possible levels: trace, debug, info, warning, error, fatal
- timeUnit : "second", # possible units: ns, us, ms, sec, min, h, d, or extensions of that, like 'second'
- variables : {
- : [, , ],
- # ...
- }},
-base : { # mandatory parent-case
- description : "",
- spec: { # any variable setting or result specification
- # optional special variables: stepSize, stopTime
- # variable key format: [@