diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml
index 6e0e1d603..a22607d23 100644
--- a/.github/workflows/pypi-publish.yml
+++ b/.github/workflows/pypi-publish.yml
@@ -58,11 +58,11 @@ jobs:
run: poetry version ${{ env.RELEASE_VERSION }}
- name: check version
run: |
- version=$(poetry run python -c "import flow360; print(flow360.__version__)")
+ version=$(poetry run python -c "import flow360; print(flow360.version.__version__)")
publish_version="${{ env.RELEASE_VERSION }}"
publish_version="${publish_version:1}"
if [ "$version" != "$publish_version" ]; then
- echo "version ${version}!=${publish_version} in flow360.__version__ does not match to release version ${{ inputs.version }}"
+ echo "version ${version}!=${publish_version} in flow360.version.__version__ does not match to release version ${{ inputs.version }}"
exit 1
fi
- name: Setup pipy token
diff --git a/.github/workflows/sync-main-to-develop.yml b/.github/workflows/sync-main-to-develop.yml
index 3fd49aa8d..17c731cdd 100644
--- a/.github/workflows/sync-main-to-develop.yml
+++ b/.github/workflows/sync-main-to-develop.yml
@@ -145,19 +145,46 @@ jobs:
- name: Open PR main -> develop (on conflict OR push failure)
if: steps.up.outputs.up_to_date == 'false' && (steps.merge.outputs.conflicted == 'true' || steps.push.outputs.exit_code != '0')
- uses: repo-sync/pull-request@v2
+ id: pr
+ shell: bash
+ run: |
+ PR_BODY=$(cat <<'EOF'
+ Automated sync needs review:
+ - Merge conflicted: ${{ steps.merge.outputs.conflicted == 'true' }}
+ - Direct push exit code: ${{ steps.push.outputs.exit_code || 'n/a' }}
+ Please resolve and merge to bring `develop` up to date with `main`.
+ EOF
+ )
+ PR_URL=$(gh pr create \
+ --base develop \
+ --head main \
+ --title "Scheduled sync: main → develop" \
+ --body "$PR_BODY")
+ echo "pr_url=$PR_URL" >> "$GITHUB_OUTPUT"
+ echo "Created PR: $PR_URL"
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Send Slack notification
+ if: steps.up.outputs.up_to_date == 'false' && (steps.merge.outputs.conflicted == 'true' || steps.push.outputs.exit_code != '0')
+ uses: slackapi/slack-github-action@v2
with:
- source_branch: "main"
- destination_branch: "develop"
- pr_title: "Scheduled sync: main → develop"
- pr_body: |
- Automated sync needs review:
- - Merge conflicted: ${{ steps.merge.outputs.conflicted == 'true' }}
- - Direct push exit code: ${{ steps.push.outputs.exit_code || 'n/a' }}
- Please resolve and merge to bring `develop` up to date with `main`.
- github_token: ${{ secrets.GITHUB_TOKEN }}
- # If using bot PAT, switch to:
- # github_token: ${{ secrets.BOT_PAT }}
+ webhook-type: incoming-webhook
+ payload: |
+ {
+ "text": " 🔄 Sync PR Created: main → develop",
+ "blocks": [
+ {
+ "type": "section",
+ "text": {
+ "type": "mrkdwn",
+ "text": " 🔄 *Scheduled sync PR created*\n\n<${{ steps.pr.outputs.pr_url }}|View Pull Request>\n\n• Merge conflicted: `${{ steps.merge.outputs.conflicted == 'true' }}`\n• Direct push failed: `${{ steps.push.outputs.exit_code != '0' }}`"
+ }
+ }
+ ]
+ }
+ env:
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_MERGE_NOTIFICATION_URL }}
- name: Final summary
run: |
diff --git a/examples/advanced_simulations/aerodynamics/dynamic_derivatives/dynamic_derivatives.py b/examples/advanced_simulations/aerodynamics/dynamic_derivatives/dynamic_derivatives.py
index a495e0c59..2a1a76491 100644
--- a/examples/advanced_simulations/aerodynamics/dynamic_derivatives/dynamic_derivatives.py
+++ b/examples/advanced_simulations/aerodynamics/dynamic_derivatives/dynamic_derivatives.py
@@ -31,7 +31,7 @@
outer_radius=1.0,
height=2.5,
)
- sliding_interface = fl.RotationCylinder(
+ sliding_interface = fl.RotationVolume(
spacing_axial=0.04,
spacing_radial=0.04,
spacing_circumferential=0.04,
diff --git a/examples/advanced_simulations/rotorcraft/isolated_propeller.py b/examples/advanced_simulations/rotorcraft/isolated_propeller.py
index 76fb21568..1e43ef185 100644
--- a/examples/advanced_simulations/rotorcraft/isolated_propeller.py
+++ b/examples/advanced_simulations/rotorcraft/isolated_propeller.py
@@ -12,13 +12,21 @@
with fl.SI_unit_system:
rotating_cylinder = fl.Cylinder(
- name="Rotating zone", center=[0, 0, 0], axis=[1, 0, 0], outer_radius=2, height=0.8
+ name="Rotating zone",
+ center=[0, 0, 0],
+ axis=[1, 0, 0],
+ outer_radius=2,
+ height=0.8,
)
refinement_cylinder = fl.Cylinder(
- name="Refinement zone", center=[1.9, 0, 0], axis=[1, 0, 0], outer_radius=2, height=4
+ name="Refinement zone",
+ center=[1.9, 0, 0],
+ axis=[1, 0, 0],
+ outer_radius=2,
+ height=4,
)
slice = fl.Slice(name="Slice", normal=[1, 0, 0], origin=[0.6, 0, 0])
- volume_zone_rotating_cylinder = fl.RotationCylinder(
+ volume_zone_rotating_cylinder = fl.RotationVolume(
name="Rotation cylinder",
spacing_axial=0.05,
spacing_radial=0.05,
@@ -30,11 +38,14 @@
params = fl.SimulationParams(
meshing=fl.MeshingParams(
defaults=fl.MeshingDefaults(
- surface_max_edge_length=1, boundary_layer_first_layer_thickness=0.1 * fl.u.mm
+ surface_max_edge_length=1,
+ boundary_layer_first_layer_thickness=0.1 * fl.u.mm,
),
refinements=[
fl.UniformRefinement(
- name="Uniform refinement", spacing=0.025, entities=[refinement_cylinder]
+ name="Uniform refinement",
+ spacing=0.025,
+ entities=[refinement_cylinder],
)
],
volume_zones=[farfield, volume_zone_rotating_cylinder],
@@ -63,7 +74,10 @@
step_size=0.0025,
max_pseudo_steps=35,
CFL=fl.AdaptiveCFL(
- min=0.1, max=10000, max_relative_change=1, convergence_limiting_factor=0.5
+ min=0.1,
+ max=10000,
+ max_relative_change=1,
+ convergence_limiting_factor=0.5,
),
),
outputs=[
diff --git a/examples/basic_simulations/meshing/cube_snappy.ipynb b/examples/basic_simulations/meshing/cube_snappy.ipynb
new file mode 100644
index 000000000..5cd75e42d
--- /dev/null
+++ b/examples/basic_simulations/meshing/cube_snappy.ipynb
@@ -0,0 +1,440 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Meshing a Cube with snappyHexMesh\n",
+ "\n",
+ "This notebook shows how to mesh a simple cube using snappyHexMesh in Flow360. This is a very simple geometry to show the integration of snappyHexMesh in flow360."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 1. Create Project from geometry\n",
+ "- Load Python libraries and Flow360 client. If you use environment variables or tokens, initialize them here so later API calls can authenticate.\n",
+ "- Project is created from geometry CAD file of the cube."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "881341eb",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "487be596aba04bc1acf5b4b81230fa4a",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Output()"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "[20:19:26] INFO: Geometry successfully submitted: \n",
+ " type = Geometry \n",
+ " name = Meshing Cube with Snappy \n",
+ " id = geo-ff48cc97-5340-4b16-b3f9-7edab07c2406 \n",
+ " status = uploaded \n",
+ " \n",
+ "
\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m[20:19:26]\u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: Geometry successfully submitted: \n",
+ "\u001b[2;36m \u001b[0m type = Geometry \n",
+ "\u001b[2;36m \u001b[0m name = Meshing Cube with Snappy \n",
+ "\u001b[2;36m \u001b[0m id = geo-\u001b[93mff48cc97-5340-4b16-b3f9-7edab07c2406\u001b[0m \n",
+ "\u001b[2;36m \u001b[0m status = uploaded \n",
+ "\u001b[2;36m \u001b[0m \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ " INFO: Waiting for geometry to be processed. \n",
+ "
\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: Waiting for geometry to be processed. \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "cde6d77a626a4c54a112f84f6fa833e0",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Output()"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n"
+ ],
+ "text/plain": []
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "[20:19:56] INFO: >> Available attribute tags for grouping **faces**: \n",
+ "
\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m[20:19:56]\u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: >> Available attribute tags for grouping **faces**: \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ " INFO: >> Tag '0': groupByBodyId. Grouping with this tag results in: \n",
+ "
\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: >> Tag \u001b[32m'0'\u001b[0m: groupByBodyId. Grouping with this tag results in: \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ " INFO: >> [0]: cube.stl \n",
+ "
\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: >> \u001b[1m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m]\u001b[0m: cube.stl \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ " INFO: IDs: ['cube'] \n",
+ "
\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: IDs: \u001b[1m[\u001b[0m\u001b[32m'cube'\u001b[0m\u001b[1m]\u001b[0m \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ " INFO: >> Available attribute tags for grouping **edges**: \n",
+ "
\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: >> Available attribute tags for grouping **edges**: \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ " INFO: >> Available attribute tags for grouping **bodies**: \n",
+ "
\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: >> Available attribute tags for grouping **bodies**: \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ " INFO: >> Tag '1': groupByFile. Grouping with this tag results in: \n",
+ "
\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: >> Tag \u001b[32m'1'\u001b[0m: groupByFile. Grouping with this tag results in: \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ " INFO: >> [0]: cube.stl \n",
+ "
\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: >> \u001b[1m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m]\u001b[0m: cube.stl \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ " INFO: IDs: ['cube.stl'] \n",
+ "
\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: IDs: \u001b[1m[\u001b[0m\u001b[32m'cube.stl'\u001b[0m\u001b[1m]\u001b[0m \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ " INFO: Regrouping face entities under `faceId` tag (previous `groupByBodyId`). \n",
+ "
\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: Regrouping face entities under `faceId` tag \u001b[1m(\u001b[0mprevious `groupByBodyId`\u001b[1m)\u001b[0m. \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import flow360 as fl\n",
+ "from flow360.examples import Cube\n",
+ "\n",
+ "Cube.get_files()\n",
+ "\n",
+ "solver_version = \"snappyHex-25.8.7\"\n",
+ "project = fl.Project.from_geometry(\n",
+ " Cube.geometry, name=\"Meshing Cube with Snappy\", length_unit=\"m\", solver_version=solver_version\n",
+ ")\n",
+ "\n",
+ "geo = project.geometry\n",
+ "geo.show_available_groupings(verbose_mode=True)\n",
+ "geo.group_faces_by_tag(\"faceId\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "8206b22c",
+ "metadata": {},
+ "source": [
+ "## 2. Define meshing parameters\n",
+ "The global meshing parameters are defined with the modular meshing workflow which allows to choose the mesher for surface and volume meshes. In this case, we'll be using the snappy integration as surface meshing and the beta mesher for the volume mesh."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "f79d204f",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ " INFO: using: SI unit system for unit inference. \n",
+ "
\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: using: SI unit system for unit inference. \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "with fl.SI_unit_system:\n",
+ " farfield = fl.AutomatedFarfield()\n",
+ " meshing_params = fl.ModularMeshingWorkflow(\n",
+ " surface_meshing=fl.SnappySurfaceMeshingParams(\n",
+ " defaults=fl.SnappySurfaceMeshingDefaults(\n",
+ " min_spacing=5 * fl.u.mm, max_spacing=100 * fl.u.mm, gap_resolution=1 * fl.u.mm\n",
+ " )\n",
+ " ),\n",
+ " volume_meshing=fl.BetaVolumeMeshingParams(\n",
+ " defaults=fl.BetaVolumeMeshingDefaults(\n",
+ " boundary_layer_first_layer_thickness=0.1 * fl.u.mm\n",
+ " )\n",
+ " ),\n",
+ " zones=[farfield],\n",
+ " )"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "53735fa8",
+ "metadata": {},
+ "source": [
+ "## 3. Define SimulationParams\n",
+ "- The simulation parameters are defined in the python class fl.SimulationParams()\n",
+ "- The meshing configuration defined previously is used here."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ " INFO: using: SI unit system for unit inference. \n",
+ "
\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: using: SI unit system for unit inference. \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "with fl.SI_unit_system:\n",
+ " params = fl.SimulationParams(\n",
+ " meshing=meshing_params,\n",
+ " operating_condition=fl.AerospaceCondition(velocity_magnitude=10 * fl.u.m / fl.u.s),\n",
+ " time_stepping=fl.Steady(),\n",
+ " models=[fl.Wall(surfaces=geo[\"*\"]), fl.Freestream(surfaces=[farfield.farfield])],\n",
+ " reference_geometry=fl.ReferenceGeometry(),\n",
+ " )"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 4. Run Case"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ " INFO: using: SI unit system for unit inference. \n",
+ "
\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m \u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: using: SI unit system for unit inference. \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "[20:19:58] INFO: Successfully submitted: \n",
+ " type = Case \n",
+ " name = Case of tutorial BETDisk from Python \n",
+ " id = case-4ee479ce-e8a8-4f4b-9faf-7312c09425b9 \n",
+ " status = pending \n",
+ " \n",
+ "
\n"
+ ],
+ "text/plain": [
+ "\u001b[2;36m[20:19:58]\u001b[0m\u001b[2;36m \u001b[0m\u001b[36mINFO\u001b[0m: Successfully submitted: \n",
+ "\u001b[2;36m \u001b[0m type = Case \n",
+ "\u001b[2;36m \u001b[0m name = Case of tutorial BETDisk from Python \n",
+ "\u001b[2;36m \u001b[0m id = case-\u001b[93m4ee479ce-e8a8-4f4b-9faf-7312c09425b9\u001b[0m \n",
+ "\u001b[2;36m \u001b[0m status = pending \n",
+ "\u001b[2;36m \u001b[0m \n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "case = project.run_case(params=params, name=\"Case of tutorial BETDisk from Python\")"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "snappy-dev",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.11.13"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/examples/post_processing/field_data/time_averaged_isosurfaces.py b/examples/post_processing/field_data/time_averaged_isosurfaces.py
index 10251f88f..49ea48050 100644
--- a/examples/post_processing/field_data/time_averaged_isosurfaces.py
+++ b/examples/post_processing/field_data/time_averaged_isosurfaces.py
@@ -13,13 +13,21 @@
with fl.SI_unit_system:
rotating_cylinder = fl.Cylinder(
- name="Rotating zone", center=[0, 0, 0], axis=[1, 0, 0], outer_radius=2, height=0.8
+ name="Rotating zone",
+ center=[0, 0, 0],
+ axis=[1, 0, 0],
+ outer_radius=2,
+ height=0.8,
)
refinement_cylinder = fl.Cylinder(
- name="Refinement zone", center=[1.9, 0, 0], axis=[1, 0, 0], outer_radius=2, height=4
+ name="Refinement zone",
+ center=[1.9, 0, 0],
+ axis=[1, 0, 0],
+ outer_radius=2,
+ height=4,
)
slice = fl.Slice(name="Slice", normal=[1, 0, 0], origin=[0.6, 0, 0])
- volume_zone_rotating_cylinder = fl.RotationCylinder(
+ volume_zone_rotating_cylinder = fl.RotationVolume(
name="Rotation cylinder",
spacing_axial=0.05,
spacing_radial=0.05,
@@ -31,11 +39,14 @@
params = fl.SimulationParams(
meshing=fl.MeshingParams(
defaults=fl.MeshingDefaults(
- surface_max_edge_length=1, boundary_layer_first_layer_thickness=0.1 * fl.u.mm
+ surface_max_edge_length=1,
+ boundary_layer_first_layer_thickness=0.1 * fl.u.mm,
),
refinements=[
fl.UniformRefinement(
- name="Uniform refinement", spacing=0.025, entities=[refinement_cylinder]
+ name="Uniform refinement",
+ spacing=0.025,
+ entities=[refinement_cylinder],
)
],
volume_zones=[farfield, volume_zone_rotating_cylinder],
@@ -64,7 +75,10 @@
step_size=0.0025,
max_pseudo_steps=35,
CFL=fl.AdaptiveCFL(
- min=0.1, max=10000, max_relative_change=1, convergence_limiting_factor=0.5
+ min=0.1,
+ max=10000,
+ max_relative_change=1,
+ convergence_limiting_factor=0.5,
),
),
outputs=[
diff --git a/flow360/__init__.py b/flow360/__init__.py
index 81beb4a16..2cb5a5375 100644
--- a/flow360/__init__.py
+++ b/flow360/__init__.py
@@ -24,14 +24,33 @@
PassiveSpacing,
SurfaceRefinement,
)
-from flow360.component.simulation.meshing_param.params import (
+from flow360.component.simulation.meshing_param.meshing_specs import (
+ BetaVolumeMeshingDefaults,
MeshingDefaults,
+ OctreeSpacing,
+ SnappyCastellatedMeshControls,
+ SnappyQualityMetrics,
+ SnappySmoothControls,
+ SnappySnapControls,
+ SnappySurfaceMeshingDefaults,
+)
+from flow360.component.simulation.meshing_param.params import (
+ BetaVolumeMeshingParams,
MeshingParams,
+ ModularMeshingWorkflow,
+ SnappySurfaceMeshingParams,
+)
+from flow360.component.simulation.meshing_param.surface_mesh_refinements import (
+ SnappyBodyRefinement,
+ SnappyRegionRefinement,
+ SnappySurfaceEdgeRefinement,
)
from flow360.component.simulation.meshing_param.volume_params import (
AutomatedFarfield,
AxisymmetricRefinement,
RotationCylinder,
+ RotationVolume,
+ StructuredBoxRefinement,
UniformRefinement,
UserDefinedFarfield,
)
@@ -140,11 +159,14 @@
VolumeOutput,
)
from flow360.component.simulation.primitives import (
+ AxisymmetricBody,
Box,
CustomVolume,
Cylinder,
ImportedSurface,
ReferenceGeometry,
+ SeedpointZone,
+ SnappyBody,
)
from flow360.component.simulation.simulation_params import SimulationParams
from flow360.component.simulation.time_stepping.time_stepping import (
@@ -197,12 +219,15 @@
"SurfaceRefinement",
"AutomatedFarfield",
"AxisymmetricRefinement",
+ "StructuredBoxRefinement",
"RotationCylinder",
+ "RotationVolume",
"UniformRefinement",
"SurfaceEdgeRefinement",
"HeightBasedRefinement",
"ReferenceGeometry",
"Cylinder",
+ "AxisymmetricBody",
"AerospaceCondition",
"ThermalState",
"LiquidOperatingCondition",
@@ -306,10 +331,25 @@
"math",
"solution",
"report",
+ "ModularMeshingWorkflow",
+ "SnappySurfaceMeshingDefaults",
+ "SnappySnapControls",
+ "SnappyCastellatedMeshControls",
+ "SnappyQualityMetrics",
+ "SnappySmoothControls",
+ "SnappyBodyRefinement",
+ "SnappyRegionRefinement",
+ "SnappySurfaceEdgeRefinement",
+ "SnappyBody",
+ "SeedpointZone",
+ "SnappySurfaceMeshingParams",
+ "BetaVolumeMeshingParams",
+ "BetaVolumeMeshingDefaults",
"get_user_variable",
"show_user_variables",
"remove_user_variable",
"StopCriterion",
"MovingStatistic",
"ImportedSurface",
+ "OctreeSpacing",
]
diff --git a/flow360/component/case.py b/flow360/component/case.py
index 670e150c7..f166e5b0b 100644
--- a/flow360/component/case.py
+++ b/flow360/component/case.py
@@ -293,7 +293,7 @@ def to_case(self) -> Case:
@before_submit_only
def submit(self, force_submit: bool = False) -> Case:
"""
- submits case to cloud for running
+ Submits case to cloud for running.
"""
assert self.name
assert self.volume_mesh_id or self.other_case or self.parent_id or self.parent_case
diff --git a/flow360/component/geometry.py b/flow360/component/geometry.py
index 6c9f1d071..657269a41 100644
--- a/flow360/component/geometry.py
+++ b/flow360/component/geometry.py
@@ -173,7 +173,7 @@ def submit(self, description="", progress_callback=None, run_async=False) -> Geo
if mesh_parser.is_ugrid() and os.path.isfile(
mesh_parser.get_associated_mapbc_filename()
):
- file_name_mapbc = os.path.basename(mesh_parser.get_associated_mapbc_filename())
+ file_name_mapbc = mesh_parser.get_associated_mapbc_filename()
mapbc_files.append(file_name_mapbc)
# Files with 'main' type are treated as MASTER_FILES and are processed after uploading
@@ -236,6 +236,11 @@ class Geometry(AssetBase):
_entity_info_class = GeometryEntityInfo
_cloud_resource_type_name = "Geometry"
+ # pylint: disable=redefined-builtin
+ def __init__(self, id: Union[str, None]):
+ super().__init__(id)
+ self.snappy_body_registry = None
+
@property
def face_group_tag(self):
"getter for face_group_tag"
@@ -263,6 +268,16 @@ def body_group_tag(self):
def body_group_tag(self, new_value: str):
raise SyntaxError("Cannot set body_group_tag, use group_bodies_by_tag() instead.")
+ @property
+ def snappy_bodies(self):
+ """Getter for the snappy registry."""
+ if self.snappy_body_registry is None:
+ raise Flow360ValueError(
+ "The faces in geometry are not grouped for snappy."
+ "Please use `group_faces_for_snappy` function to group them first."
+ )
+ return self.snappy_body_registry
+
def get_dynamic_default_settings(self, simulation_dict: dict):
"""Get the default geometry settings from the simulation dict"""
@@ -412,10 +427,25 @@ def group_bodies_by_tag(self, tag_name: str) -> None:
"body", tag_name, self.internal_registry
)
+ def group_faces_for_snappy(self) -> None:
+ """
+ Group faces according to body::region convention for snappyHexMesh.
+ """
+ # pylint: disable=protected-access,no-member
+ self.internal_registry = self._entity_info._group_entity_by_tag(
+ "face", "faceId", self.internal_registry
+ )
+ # pylint: disable=protected-access
+ self.snappy_body_registry = self._entity_info._group_faces_by_snappy_format()
+
def reset_face_grouping(self) -> None:
"""Reset the face grouping"""
# pylint: disable=protected-access,no-member
self.internal_registry = self._entity_info._reset_grouping("face", self.internal_registry)
+ if self.snappy_body_registry is not None:
+ self.snappy_body_registry = self.snappy_body._reset_grouping(
+ "face", self.snappy_body_registry
+ )
def reset_edge_grouping(self) -> None:
"""Reset the edge grouping"""
diff --git a/flow360/component/results/base_results.py b/flow360/component/results/base_results.py
index ff38adc5b..1a09154b7 100644
--- a/flow360/component/results/base_results.py
+++ b/flow360/component/results/base_results.py
@@ -2,6 +2,7 @@
from __future__ import annotations
+import copy
import os
import re
import shutil
@@ -93,6 +94,11 @@ def _filter_headers_by_prefix(
A list of headers that satisfy the inclusion/exclusion criteria.
"""
+ if not include and not exclude:
+ raise RuntimeError(
+ "Invalid use of filtering, include and exclude patterns are both empty/None."
+ )
+
if suffixes is None:
pattern = re.compile(r"(.*)$")
else:
@@ -660,18 +666,29 @@ def _filtered_sum(self):
def _create_forces_group(self, entity_groups: dict[str, List[str]]) -> PerEntityResultCSVModel:
"""
Create new CSV model for the given entity groups.
+ Warning: This function will modify the current instance!!!
"""
def full_name_pattern(word: str) -> re.Pattern:
# Find the pattern that matches the name exactly or the full name (zone/boundary)
return rf"^(?:{re.escape(word)}|[^/]+/{re.escape(word)})$"
+ self.reload_data() # Remove all the imposed filters
+ print(">> _x_columns =", self._x_columns)
raw_values = {}
for x_column in self._x_columns:
raw_values[x_column] = np.array(self.raw_values[x_column])
+
for name, entities in entity_groups.items():
entity_patterns = [full_name_pattern(name) for name in entities]
- self.filter(include=entity_patterns)
+
+ # generates self.values[f"total{variable}"] for below
+ try:
+ self.filter(include=entity_patterns)
+ except RuntimeError:
+ # No entities matched the include or exclude patterns
+ continue
+
for variable in self._variables:
partial_sum = np.array(self.values[f"total{variable}"])
if f"{name}_{variable}" not in raw_values:
@@ -682,7 +699,7 @@ def full_name_pattern(word: str) -> re.Pattern:
raw_values = {key: val.tolist() for key, val in raw_values.items()}
entity_groups = {key: sorted(val) for key, val in entity_groups.items()}
- return self.from_dict(data=raw_values, group=entity_groups)
+ return self.__class__.from_dict(data=raw_values, group=entity_groups)
def by_boundary_condition(self, params: SimulationParams) -> PerEntityResultCSVModel:
"""
@@ -699,7 +716,9 @@ def by_boundary_condition(self, params: SimulationParams) -> PerEntityResultCSVM
entity_groups[boundary_name].extend(
[entity.name for entity in model.entities.stored_entities]
)
- return self._create_forces_group(entity_groups=entity_groups)
+ self_copy = copy.deepcopy(self) # Shield from modifying the current instance
+ # pylint: disable=protected-access
+ return self_copy._create_forces_group(entity_groups=entity_groups)
def by_body_group(self, params: SimulationParams) -> PerEntityResultCSVModel:
"""
@@ -722,7 +741,9 @@ def by_body_group(self, params: SimulationParams) -> PerEntityResultCSVModel:
"please upgrade the project to the latest version and re-run the case."
)
entity_groups = entity_info.get_body_group_to_face_group_name_map()
- return self._create_forces_group(entity_groups=entity_groups)
+ self_copy = copy.deepcopy(self) # Shield from modifying the current instance
+ # pylint: disable=protected-access
+ return self_copy._create_forces_group(entity_groups=entity_groups)
def reload_data(self, filter_physical_steps_only: bool = False, include_time: bool = False):
"""
diff --git a/flow360/component/results/case_results.py b/flow360/component/results/case_results.py
index 49aa552ed..c07d08936 100644
--- a/flow360/component/results/case_results.py
+++ b/flow360/component/results/case_results.py
@@ -71,7 +71,6 @@
_HEAT_FLUX = "HeatFlux"
_X = "X"
_Y = "Y"
-_STRIDE = "stride"
_CUMULATIVE_CD_CURVE = "Cumulative_CD_Curve"
_CD_PER_STRIP = "CD_per_strip"
_CFx_PER_SPAN = "CFx_per_span"
@@ -276,7 +275,7 @@ class YSlicingForceDistributionResultCSVModel(PerEntityResultCSVModel):
_variables: List[str] = [_CFx_PER_SPAN, _CFz_PER_SPAN, _CMy_PER_SPAN]
_filter_when_zero = [_CFx_PER_SPAN, _CFz_PER_SPAN, _CMy_PER_SPAN]
- _x_columns: List[str] = [_Y, _STRIDE]
+ _x_columns: List[str] = [_Y]
class SurfaceHeatTransferResultCSVModel(PerEntityResultCSVModel, TimeSeriesResultCSVModel):
diff --git a/flow360/component/simulation/entity_info.py b/flow360/component/simulation/entity_info.py
index ee60e537d..47cc354d2 100644
--- a/flow360/component/simulation/entity_info.py
+++ b/flow360/component/simulation/entity_info.py
@@ -7,7 +7,10 @@
import pydantic as pd
from flow360.component.simulation.framework.base_model import Flow360BaseModel
-from flow360.component.simulation.framework.entity_registry import EntityRegistry
+from flow360.component.simulation.framework.entity_registry import (
+ EntityRegistry,
+ SnappyBodyRegistry,
+)
from flow360.component.simulation.outputs.output_entities import (
Point,
PointArray,
@@ -23,6 +26,7 @@
GeometryBodyGroup,
GhostCircularPlane,
GhostSphere,
+ SnappyBody,
Surface,
)
from flow360.component.simulation.unit_system import LengthType
@@ -142,7 +146,7 @@ class GeometryEntityInfo(EntityInfoModel):
def group_in_registry(
self,
- entity_type_name: Literal["face", "edge", "body"],
+ entity_type_name: Literal["face", "edge", "body", "snappy_body"],
attribute_name: str,
registry: EntityRegistry,
) -> EntityRegistry:
@@ -155,15 +159,31 @@ def group_in_registry(
known_frozen_hashes = registry.fast_register(item, known_frozen_hashes)
return registry
+ def _get_snappy_bodies(self) -> List[SnappyBody]:
+
+ snappy_body_mapping = {}
+ for patch in self.grouped_faces[self.face_attribute_names.index("faceId")]:
+ name_components = patch.name.split("::")
+ body_name = name_components[0]
+ if body_name not in snappy_body_mapping:
+ snappy_body_mapping[body_name] = []
+ if patch not in snappy_body_mapping[body_name]:
+ snappy_body_mapping[body_name].append(patch)
+
+ return [
+ SnappyBody(name=snappy_body, surfaces=body_entities)
+ for snappy_body, body_entities in snappy_body_mapping.items()
+ ]
+
def _get_list_of_entities(
self,
attribute_name: Union[str, None] = None,
- entity_type_name: Literal["face", "edge", "body"] = None,
- ) -> Union[List[Surface], List[Edge], List[GeometryBodyGroup]]:
+ entity_type_name: Literal["face", "edge", "body", "snappy_body"] = None,
+ ) -> Union[List[Surface], List[Edge], List[GeometryBodyGroup], List[SnappyBody]]:
# Validations
if entity_type_name is None:
raise ValueError("Entity type name is required.")
- if entity_type_name not in ["face", "edge", "body"]:
+ if entity_type_name not in ["face", "edge", "body", "snappy_body"]:
raise ValueError(
f"Invalid entity type name, expected 'body, 'face' or 'edge' but got {entity_type_name}."
)
@@ -175,10 +195,12 @@ def _get_list_of_entities(
entity_attribute_names = self.edge_attribute_names
entity_full_list = self.grouped_edges
specified_attribute_name = self.edge_group_tag
- else:
+ elif entity_type_name == "body":
entity_attribute_names = self.body_attribute_names
entity_full_list = self.grouped_bodies
specified_attribute_name = self.body_group_tag
+ else:
+ return self._get_snappy_bodies()
# Use the supplied one if not None
if attribute_name is not None:
@@ -348,11 +370,20 @@ def _group_entity_by_tag(
return registry
+ def _group_faces_by_snappy_format(self):
+ registry = SnappyBodyRegistry()
+
+ registry = self.group_in_registry("snappy_body", attribute_name="faceId", registry=registry)
+
+ return registry
+
+ @pd.validate_call
def _reset_grouping(
self, entity_type_name: Literal["face", "edge", "body"], registry: EntityRegistry
) -> EntityRegistry:
if entity_type_name == "face":
registry.clear(Surface)
+ registry.clear(SnappyBody)
with model_attribute_unlock(self, "face_group_tag"):
self.face_group_tag = None
elif entity_type_name == "edge":
diff --git a/flow360/component/simulation/framework/base_model.py b/flow360/component/simulation/framework/base_model.py
index ae082bee2..46c34d835 100644
--- a/flow360/component/simulation/framework/base_model.py
+++ b/flow360/component/simulation/framework/base_model.py
@@ -544,8 +544,29 @@ def _handle_dict_with_hash(cls, model_dict):
@classmethod
def _calculate_hash(cls, model_dict):
+ def remove_private_attribute_id(obj):
+ """
+ Recursively remove all 'private_attribute_id' keys from the data structure.
+ This ensures hash consistency when private_attribute_id contains UUID4 values
+ that change between runs.
+ """
+ if isinstance(obj, dict):
+ # Create new dict excluding 'private_attribute_id' keys
+ return {
+ key: remove_private_attribute_id(value)
+ for key, value in obj.items()
+ if key != "private_attribute_id"
+ }
+ if isinstance(obj, list):
+ # Recursively process list elements
+ return [remove_private_attribute_id(item) for item in obj]
+ # Return other types as-is (maintains reference for immutable objects)
+ return obj
+
+ # Remove private_attribute_id before calculating hash
+ cleaned_dict = remove_private_attribute_id(model_dict)
hasher = hashlib.sha256()
- json_string = json.dumps(model_dict, sort_keys=True)
+ json_string = json.dumps(cleaned_dict, sort_keys=True)
hasher.update(json_string.encode("utf-8"))
return hasher.hexdigest()
@@ -642,7 +663,10 @@ def preprocess(
required_by = []
solver_values = self._nondimensionalization(
- params=params, exclude=exclude, required_by=required_by, registry_lookup=registry_lookup
+ params=params,
+ exclude=exclude,
+ required_by=required_by,
+ registry_lookup=registry_lookup,
)
for property_name, value in self.__dict__.items():
if property_name in exclude:
diff --git a/flow360/component/simulation/framework/entity_base.py b/flow360/component/simulation/framework/entity_base.py
index f13bc1b88..316065c5c 100644
--- a/flow360/component/simulation/framework/entity_base.py
+++ b/flow360/component/simulation/framework/entity_base.py
@@ -266,6 +266,7 @@ def _valid_individual_input(cls, input_data):
"Expected entity instance."
)
+ # pylint: disable=too-many-branches
@pd.model_validator(mode="before")
@classmethod
def _format_input_to_list(cls, input_data: Union[dict, list]):
diff --git a/flow360/component/simulation/framework/entity_registry.py b/flow360/component/simulation/framework/entity_registry.py
index 7bcfa47a8..a77332cb5 100644
--- a/flow360/component/simulation/framework/entity_registry.py
+++ b/flow360/component/simulation/framework/entity_registry.py
@@ -7,6 +7,37 @@
from flow360.component.simulation.framework.base_model import Flow360BaseModel
from flow360.component.simulation.framework.entity_base import EntityBase
from flow360.component.utils import _naming_pattern_handler
+from flow360.exceptions import Flow360ValueError
+
+
+class DoubleIndexableList(list):
+ """
+ An extension of a list that allows accessing elements inside it through a string key.
+ """
+
+ def __getitem__(self, key: Union[str, slice, int]):
+ if isinstance(key, str):
+ returned_items = []
+ for item in self:
+ try:
+ item_ret_value = item[key]
+ except KeyError:
+ item_ret_value = []
+ except Exception as e:
+ raise ValueError(
+ f"Trying to access something in {item} through string indexing, which is not allowed."
+ ) from e
+ if isinstance(item_ret_value, list):
+ returned_items += item_ret_value
+ else:
+ returned_items.append(item_ret_value)
+ if not returned_items:
+ raise ValueError(
+ "No entity found in registry for parent entities: "
+ + f"{', '.join([f'{entity.name}' for entity in self])} with given name/naming pattern: '{key}'."
+ )
+ return returned_items
+ return super().__getitem__(key)
class EntityRegistryBucket:
@@ -227,3 +258,48 @@ def find_by_asset_id(self, *, entity_id: str, entity_class: type[EntityBase]):
def is_empty(self):
"""Return True if the registry is empty, False otherwise."""
return not self.internal_registry
+
+
+class SnappyBodyRegistry(EntityRegistry):
+ """
+ Extension of Entityregistry to be used with SnappyBody, allows double indexing.
+ """
+
+ def find_by_naming_pattern(
+ self, pattern: str, enforce_output_as_list: bool = True, error_when_no_match: bool = False
+ ) -> list[EntityBase]:
+ """
+ Finds all registered entities whose names match a given pattern.
+
+ Parameters:
+ pattern (str): A naming pattern, which can include '*' as a wildcard.
+
+ Returns:
+ List[EntityBase]: A list of entities whose names match the pattern.
+ """
+ matched_entities = DoubleIndexableList()
+ regex = _naming_pattern_handler(pattern=pattern)
+ # pylint: disable=no-member
+ for entity_list in self.internal_registry.values():
+ matched_entities.extend(filter(lambda x: regex.match(x.name), entity_list))
+
+ if not matched_entities and error_when_no_match is True:
+ raise ValueError(
+ f"No entity found in registry with given name/naming pattern: '{pattern}'."
+ )
+ if enforce_output_as_list is False and len(matched_entities) == 1:
+ return matched_entities[0]
+
+ return matched_entities
+
+ def __getitem__(self, key):
+ """
+ Get the entity by name.
+ `key` is the name of the entity or the naming pattern if wildcard is used.
+ """
+ if isinstance(key, str) is False:
+ raise Flow360ValueError(f"Entity naming pattern: {key} is not a string.")
+
+ return self.find_by_naming_pattern(
+ key, enforce_output_as_list=False, error_when_no_match=True
+ )
diff --git a/flow360/component/simulation/framework/param_utils.py b/flow360/component/simulation/framework/param_utils.py
index 691be7844..67a2c4eb9 100644
--- a/flow360/component/simulation/framework/param_utils.py
+++ b/flow360/component/simulation/framework/param_utils.py
@@ -152,6 +152,7 @@ def register_entity_list(model: Flow360BaseModel, registry: EntityRegistry) -> N
register_entity_list(field, registry)
+# pylint: disable=too-many-branches
def _update_entity_full_name(
model: Flow360BaseModel,
target_entity_type: Union[type[_SurfaceEntityBase], type[_VolumeEntityBase]],
@@ -170,20 +171,36 @@ def _update_entity_full_name(
field._update_entity_info_with_metadata(volume_mesh_meta_data)
if isinstance(field, EntityList):
+ added_entities = []
for entity in field.stored_entities:
if isinstance(entity, target_entity_type):
# pylint: disable=protected-access
- entity._update_entity_info_with_metadata(volume_mesh_meta_data)
+ partial_additions = entity._update_entity_info_with_metadata(
+ volume_mesh_meta_data
+ )
+ if partial_additions is not None:
+ added_entities.extend(partial_additions)
+ field.stored_entities.extend(added_entities)
elif isinstance(field, (list, tuple)):
+ added_entities = []
for item in field:
if isinstance(item, target_entity_type):
- item._update_entity_info_with_metadata( # pylint: disable=protected-access
- volume_mesh_meta_data
+ partial_additions = (
+ item._update_entity_info_with_metadata( # pylint: disable=protected-access
+ volume_mesh_meta_data
+ )
)
+ if partial_additions is not None:
+ added_entities.extend(partial_additions)
elif isinstance(item, Flow360BaseModel):
_update_entity_full_name(item, target_entity_type, volume_mesh_meta_data)
+ if isinstance(field, list):
+ field.extend(added_entities)
+ if isinstance(field, tuple):
+ field += tuple(added_entities)
+
elif isinstance(field, Flow360BaseModel):
_update_entity_full_name(field, target_entity_type, volume_mesh_meta_data)
diff --git a/flow360/component/simulation/framework/updater.py b/flow360/component/simulation/framework/updater.py
index 7198bad58..91c8150a3 100644
--- a/flow360/component/simulation/framework/updater.py
+++ b/flow360/component/simulation/framework/updater.py
@@ -367,6 +367,15 @@ def _to_25_7_2(params_as_dict):
return params_as_dict
+def _to_25_8_0(params_as_dict):
+ # new method of specifying meshing was added, as well as the method discriminator
+ meshing = params_as_dict.get("meshing")
+ if meshing:
+ meshing["type_name"] = "MeshingParams"
+
+ return params_as_dict
+
+
VERSION_MILESTONES = [
(Flow360Version("24.11.1"), _to_24_11_1),
(Flow360Version("24.11.7"), _to_24_11_7),
@@ -380,6 +389,7 @@ def _to_25_7_2(params_as_dict):
(Flow360Version("25.6.5"), _to_25_6_5),
(Flow360Version("25.6.6"), _to_25_6_6),
(Flow360Version("25.7.2"), _to_25_7_2),
+ (Flow360Version("25.8.0"), _to_25_8_0),
] # A list of the Python API version tuple with there corresponding updaters.
diff --git a/flow360/component/simulation/meshing_param/edge_params.py b/flow360/component/simulation/meshing_param/edge_params.py
index 1379b1499..433b7ecc1 100644
--- a/flow360/component/simulation/meshing_param/edge_params.py
+++ b/flow360/component/simulation/meshing_param/edge_params.py
@@ -8,6 +8,9 @@
from flow360.component.simulation.framework.entity_base import EntityList
from flow360.component.simulation.primitives import Edge
from flow360.component.simulation.unit_system import AngleType, LengthType
+from flow360.component.simulation.validation.validation_context import (
+ get_validation_info,
+)
class AngleBasedRefinement(Flow360BaseModel):
@@ -104,3 +107,13 @@ class SurfaceEdgeRefinement(Flow360BaseModel):
description="Method for determining the spacing. See :class:`AngleBasedRefinement`,"
" :class:`HeightBasedRefinement`, :class:`AspectRatioBasedRefinement`, :class:`ProjectAnisoSpacing`",
)
+
+ @pd.model_validator(mode="after")
+ def ensure_not_geometry_ai(self):
+ """Ensure that geometry AI is disabled when using this feature."""
+ validation_info = get_validation_info()
+ if validation_info is None:
+ return self
+ if validation_info.use_geometry_AI:
+ raise ValueError("SurfaceEdgeRefinement is not currently supported with geometry AI.")
+ return self
diff --git a/flow360/component/simulation/meshing_param/meshing_specs.py b/flow360/component/simulation/meshing_param/meshing_specs.py
new file mode 100644
index 000000000..d40eff6b3
--- /dev/null
+++ b/flow360/component/simulation/meshing_param/meshing_specs.py
@@ -0,0 +1,484 @@
+"""Default settings for meshing using different meshing algorithms"""
+
+from math import log2
+from typing import Optional
+
+import numpy as np
+import pydantic as pd
+from typing_extensions import Self
+
+import flow360.component.simulation.units as u
+from flow360.component.simulation.framework.base_model import Flow360BaseModel
+from flow360.component.simulation.framework.updater import DEFAULT_PLANAR_FACE_TOLERANCE
+from flow360.component.simulation.unit_system import AngleType, AreaType, LengthType
+from flow360.component.simulation.validation.validation_context import (
+ SURFACE_MESH,
+ VOLUME_MESH,
+ ConditionalField,
+ ContextField,
+ get_validation_info,
+)
+
+
+class MeshingDefaults(Flow360BaseModel):
+ """
+ Default/global settings for meshing parameters.
+
+ Example
+ -------
+
+ >>> fl.MeshingDefaults(
+ ... surface_max_edge_length=1*fl.u.m,
+ ... surface_edge_growth_rate=1.2,
+ ... curvature_resolution_angle=12*fl.u.deg,
+ ... boundary_layer_growth_rate=1.1,
+ ... boundary_layer_first_layer_thickness=1e-5*fl.u.m
+ ... )
+
+ ====
+ """
+
+ # pylint: disable=no-member
+ geometry_accuracy: Optional[LengthType.Positive] = pd.Field(
+ None,
+ description="The smallest length scale that will be resolved accurately by the surface meshing process. "
+ "This parameter is only valid when using geometry AI."
+ "It can be overridden with class: ~flow360.GeometryRefinement.",
+ )
+
+ ##:: Default surface edge settings
+ surface_edge_growth_rate: float = ContextField(
+ 1.2,
+ ge=1,
+ description="Growth rate of the anisotropic layers grown from the edges."
+ "This can not be overridden per edge.",
+ context=SURFACE_MESH,
+ )
+
+ ##:: Default boundary layer settings
+ boundary_layer_growth_rate: float = ContextField(
+ 1.2,
+ description="Default growth rate for volume prism layers.",
+ ge=1,
+ context=VOLUME_MESH,
+ )
+ # pylint: disable=no-member
+ boundary_layer_first_layer_thickness: Optional[LengthType.Positive] = ConditionalField(
+ None,
+ description="Default first layer thickness for volumetric anisotropic layers."
+ " This can be overridden with :class:`~flow360.BoundaryLayer`.",
+ context=VOLUME_MESH,
+ ) # Truly optional if all BL faces already have first_layer_thickness
+
+ number_of_boundary_layers: Optional[pd.NonNegativeInt] = pd.Field(
+ None,
+ description="Default number of volumetric anisotropic layers."
+ " The volume mesher will automatically calculate the required"
+ " no. of layers to grow the boundary layer elements to isotropic size if not specified."
+ " This is only supported by the beta mesher and can not be overridden per face.",
+ )
+
+ planar_face_tolerance: Optional[pd.NonNegativeFloat] = pd.Field(
+ DEFAULT_PLANAR_FACE_TOLERANCE,
+ description="Tolerance used for detecting planar faces in the input surface mesh / geometry"
+ " that need to be remeshed, such as symmetry planes."
+ " This tolerance is non-dimensional, and represents a distance"
+ " relative to the largest dimension of the bounding box of the input surface mesh / geometry."
+ " This can not be overridden per face.",
+ )
+
+ ##:: Default surface layer settings
+ surface_max_edge_length: Optional[LengthType.Positive] = ConditionalField(
+ None,
+ description="Default maximum edge length for surface cells."
+ " This can be overridden with :class:`~flow360.SurfaceRefinement`.",
+ context=SURFACE_MESH,
+ )
+
+ surface_max_aspect_ratio: Optional[pd.PositiveFloat] = ConditionalField(
+ 10.0,
+ description="Maximum aspect ratio for surface cells for the GAI surface mesher."
+ " This cannot be overridden per face",
+ context=SURFACE_MESH,
+ )
+
+ surface_max_adaptation_iterations: Optional[pd.NonNegativeInt] = ConditionalField(
+ 50,
+ description="Maximum adaptation iterations for the GAI surface mesher.",
+ context=SURFACE_MESH,
+ )
+
+ curvature_resolution_angle: Optional[AngleType.Positive] = ContextField(
+ 12 * u.deg,
+ description=(
+ "Default maximum angular deviation in degrees. This value will restrict:"
+ " 1. The angle between a cell’s normal and its underlying surface normal."
+ " 2. The angle between a line segment’s normal and its underlying curve normal."
+ " This can not be overridden per face."
+ ),
+ context=SURFACE_MESH,
+ )
+
+ preserve_thin_geometry: Optional[bool] = pd.Field(
+ False,
+ description="Flag to specify whether thin geometry features with thickness roughly equal "
+ + "to geometry_accuracy should be resolved accurately during the surface meshing process."
+ + "This can be overridden with class: ~flow360.GeometryRefinement",
+ )
+
+ @pd.field_validator("number_of_boundary_layers", mode="after")
+ @classmethod
+ def invalid_number_of_boundary_layers(cls, value):
+ """Ensure number of boundary layers is not specified"""
+ validation_info = get_validation_info()
+
+ if validation_info is None:
+ return value
+
+ if value is not None and not validation_info.is_beta_mesher:
+ raise ValueError("Number of boundary layers is only supported by the beta mesher.")
+ return value
+
+ @pd.field_validator("geometry_accuracy", mode="after")
+ @classmethod
+ def invalid_geometry_accuracy(cls, value):
+ """Ensure geometry accuracy is not specified when GAI is not used"""
+ validation_info = get_validation_info()
+
+ if validation_info is None:
+ return value
+
+ if value is not None and not validation_info.use_geometry_AI:
+ raise ValueError("Geometry accuracy is only supported when geometry AI is used.")
+
+ if value is None and validation_info.use_geometry_AI:
+ raise ValueError("Geometry accuracy is required when geometry AI is used.")
+ return value
+
+ @pd.field_validator(
+ "surface_max_aspect_ratio",
+ "surface_max_adaptation_iterations",
+ "preserve_thin_geometry",
+ mode="after",
+ )
+ @classmethod
+ def invalid_geometry_ai_features(cls, value, info):
+ """Ensure surface max aspect ratio is not specified when GAI is not used"""
+ validation_info = get_validation_info()
+
+ if validation_info is None:
+ return value
+
+ # pylint: disable=unsubscriptable-object
+ default_value = cls.model_fields[info.field_name].default
+ if value != default_value and not validation_info.use_geometry_AI:
+ raise ValueError(f"{info.field_name} is only supported when geometry AI is used.")
+
+ return value
+
+
+class BetaVolumeMeshingDefaults(Flow360BaseModel):
+ """
+ Default/global settings for volume meshing parameters. To be used with class:`ModularMeshingWorkflow`.
+ """
+
+ ##:: Default boundary layer settings
+ boundary_layer_growth_rate: float = pd.Field(
+ 1.2,
+ description="Default growth rate for volume prism layers.",
+ ge=1,
+ )
+ # pylint: disable=no-member
+ boundary_layer_first_layer_thickness: LengthType.Positive = pd.Field(
+ description="Default first layer thickness for volumetric anisotropic layers."
+ " This can be overridden with :class:`~flow360.BoundaryLayer`.",
+ )
+
+ number_of_boundary_layers: Optional[pd.NonNegativeInt] = pd.Field(
+ None,
+ description="Default number of volumetric anisotropic layers."
+ " The volume mesher will automatically calculate the required"
+ " no. of layers to grow the boundary layer elements to isotropic size if not specified."
+ " This is only supported by the beta mesher and can not be overridden per face.",
+ )
+
+
+class SnappySurfaceMeshingDefaults(Flow360BaseModel):
+ """
+ Default/global settings for snappyHexMesh surface meshing parameters.
+ To be used with class:`ModularMeshingWorkflow`.
+ """
+
+ # pylint: disable=no-member
+ min_spacing: LengthType.Positive = pd.Field()
+ max_spacing: LengthType.Positive = pd.Field()
+ gap_resolution: LengthType.Positive = pd.Field()
+
+ @pd.model_validator(mode="after")
+ def _check_spacing_order(self) -> Self:
+ if self.min_spacing and self.max_spacing:
+ if self.min_spacing > self.max_spacing:
+ raise ValueError("Minimum spacing must be lower than maximum spacing.")
+ return self
+
+
+class SnappyQualityMetrics(Flow360BaseModel):
+ """
+ Mesh quality control parameters for snappyHexMesh meshing process.
+
+ Parameters
+ ----------
+ max_non_ortho : Optional[AngleType.Positive], default: 85°
+ Maximum face non-orthogonality angle: the angle made by the vector between
+ the two adjacent cell centres across the common face and the face normal.
+ Set to None to disable this metric.
+
+ max_boundary_skewness : Optional[AngleType], default: 20°
+ Maximum boundary skewness. Set to None or -1° to disable this metric.
+
+ max_internal_skewness : Optional[AngleType], default: 50°
+ Maximum internal face skewness. Set to None or -1° to disable this metric.
+
+ max_concave : Optional[AngleType.Positive], default: 50°
+ Maximum cell concavity. Set to None to disable this metric.
+
+ min_vol : Optional[float], default: None
+ Minimum cell pyramid volume [m³].
+ Set to None to disable this metric (uses -1e30 internally).
+
+ min_tet_quality : Optional[float], default: None
+ Minimum tetrahedron quality.
+ Set to None to disable this metric (uses -1e30 internally).
+
+ min_area : Optional[AreaType.Positive], default: None
+ Minimum face area. Set to None to disable.
+
+ min_twist : Optional[float], default: None
+ Minimum twist. Controls the twist quality of faces.
+ Set to None to disable this metric.
+
+ min_determinant : Optional[float], default: None
+ Minimum cell determinant. Set to None to disable this metric (uses -1e30 internally).
+
+ min_vol_ratio : float, default: 0
+ Minimum volume ratio between adjacent cells.
+
+ min_face_weight : float, default: 0
+ Minimum face interpolation weight. Controls the quality of face interpolation.
+
+ min_triangle_twist : Optional[float], default: None
+ Minimum triangle twist. Set to None to disable this metric.
+
+ n_smooth_scale : Optional[pd.NonNegativeInt], default: 4
+ Number of smoothing iterations. Used in combination with error_reduction.
+
+ error_reduction : Optional[float], default: 0.75
+ Error reduction factor. Used in combination with n_smooth_scale.
+ Must be between 0 and 1.
+
+ min_vol_collapse_ratio : float, default: 0
+ Minimum volume collapse ratio. If > 0: preserves single cells with all points
+ on the surface if the resulting volume after snapping is larger than
+ min_vol_collapse_ratio times the old volume (i.e., not collapsed to flat cell).
+ If < 0: always deletes such cells.
+ """
+
+ # pylint: disable=no-member
+ max_non_ortho: Optional[AngleType.Positive] = pd.Field(default=85 * u.deg)
+ max_boundary_skewness: Optional[AngleType] = pd.Field(default=20 * u.deg)
+ max_internal_skewness: Optional[AngleType] = pd.Field(default=50 * u.deg)
+ max_concave: Optional[AngleType.Positive] = pd.Field(default=50 * u.deg)
+ min_vol: Optional[float] = pd.Field(default=None)
+ min_tet_quality: Optional[float] = pd.Field(default=None)
+ min_area: Optional[AreaType.Positive] = pd.Field(default=None)
+ min_twist: Optional[float] = pd.Field(default=None)
+ min_determinant: Optional[float] = pd.Field(default=None)
+ min_vol_ratio: Optional[float] = pd.Field(default=0)
+ min_face_weight: Optional[float] = pd.Field(default=0)
+ min_triangle_twist: Optional[float] = pd.Field(default=None)
+ n_smooth_scale: Optional[pd.NonNegativeInt] = pd.Field(default=4, ge=0)
+ error_reduction: Optional[float] = pd.Field(default=0.75, ge=0, le=1)
+ min_vol_collapse_ratio: Optional[float] = pd.Field(0)
+
+ @pd.field_validator("max_non_ortho", "max_concave", mode="after")
+ @classmethod
+ def disable_angle_metrics_w_defaults(cls, value):
+ """Disable a quality metric in OpenFOAM by setting a specific value."""
+ if value is None:
+ return 180 * u.deg
+ if value > 180 * u.deg:
+ raise ValueError("Value must be less that 180 degrees.")
+ return value
+
+ @pd.field_validator("max_boundary_skewness", "max_internal_skewness", mode="after")
+ @classmethod
+ def disable_skewness_metric(cls, value):
+ """Disable a quality metric in OpenFOAM by setting a specific value."""
+ if value is None:
+ return -1 * u.deg
+ if value.to("degree") <= 0 * u.deg and value.to("degree") != -1 * u.deg:
+ raise ValueError(
+ f"Maximum skewness must be positive (your value: {value}). To disable enter None or -1*u.deg."
+ )
+ return value
+
+ @pd.field_validator("min_vol", "min_tet_quality", "min_determinant", mode="after")
+ @classmethod
+ def disable_by_low_value(cls, value):
+ """Disable a quality metric in OpenFOAM by setting a specific value."""
+ if value is None:
+ return -1e30
+ return value
+
+ @pd.field_validator("n_smooth_scale", "error_reduction", mode="after")
+ @classmethod
+ def disable_by_zero(cls, value):
+ """Disable a quality metric in OpenFOAM by setting a specific value."""
+ if value is None:
+ return 0
+ return value
+
+
+class SnappyCastellatedMeshControls(Flow360BaseModel):
+ """
+ snappyHexMesh castellation controls.
+
+ Parameters
+ ----------
+ resolve_feature_angle : Optional[AngleType.Positive], default: 25°
+ This parameter controls the local curvature refinement. The higher the value,
+ the less features it captures. Applies maximum level of refinement to cells
+ that can see intersections whose angle exceeds this value.
+
+ n_cells_between_levels: Optional[pd.NonNegativeInt], default: 1
+ This parameter controls the transition between cell refinement levels. Number
+ of buffer layers of cells between different levels of refinement.
+
+ min_refinement_cells: Optional[pd.NonNegativeInt], default: 10
+ The refinement along the surfaces may spend many iterations on refinement of
+ only few cells. Whenever the number of cells to be refined is less than or equal
+ to this value, the refinement will stop. Unless the parameter is set to zero,
+ at least one refining iteration will be performed.
+ """
+
+ # pylint: disable=no-member
+ resolve_feature_angle: Optional[AngleType.Positive] = pd.Field(default=25 * u.deg)
+ n_cells_between_levels: Optional[pd.NonNegativeInt] = pd.Field(1)
+ min_refinement_cells: Optional[pd.NonNegativeInt] = pd.Field(10)
+
+ @pd.field_validator("resolve_feature_angle", mode="after")
+ @classmethod
+ def angle_limits(cls, value):
+ """Limit angular values."""
+ if value is None:
+ return value
+ if value > 180 * u.deg:
+ raise ValueError("resolve_feature_angle must be between 0 and 180 degrees.")
+ return value
+
+
+class SnappySnapControls(Flow360BaseModel):
+ """
+ snappyHexMesh snap controls.
+
+ Parameters
+ ----------
+ n_smooth_patch: pd.NonNegativeInt, default: 3
+ Number of patch smoothing iterations before finding correspondence to surface.
+
+ tolerance: pd.PositiveFloat, default: 2
+ Ratio of distance for points to be attracted by surface feature point or edge,
+ to local maximum edge length.
+
+ n_solve_iter: pd.NonNegativeInt, default: 30
+ Number of mesh displacement relaxation iterations
+
+ n_relax_iter: pd.NonNegativeInt, default: 5
+ Number of relaxation iterations during the snapping. If the mesh does not conform the geometry
+ and all the iterations are spend, user may try to increase the number of iterations.
+
+ n_feature_snap_iter: pd.NonNegativeInt, default: 15
+ Number of relaxation iterations used for snapping onto the features.
+ If not specified, feature snapping will be disabled.
+
+ multi_region_feature_snap: bool, default: True
+ When using explicitFeatureSnap and this switch is on, features between multiple
+ surfaces will be captured. This is useful for multi-region meshing where the internal
+ mesh must conform the region geometrical boundaries.
+
+ strict_region_snap: bool, default: False
+ Attract points only to the surface they originate from. This can improve snapping of
+ intersecting surfaces.
+ """
+
+ # pylint: disable=no-member
+ n_smooth_patch: pd.NonNegativeInt = pd.Field(3)
+ tolerance: pd.PositiveFloat = pd.Field(2)
+ n_solve_iter: pd.NonNegativeInt = pd.Field(30)
+ n_relax_iter: pd.NonNegativeInt = pd.Field(5)
+ n_feature_snap_iter: pd.NonNegativeInt = pd.Field(15)
+ multi_region_feature_snap: bool = pd.Field(True)
+ strict_region_snap: bool = pd.Field(False)
+
+
+class SnappySmoothControls(Flow360BaseModel):
+ """
+ snappyHexMesh smoothing controls.
+
+ Parameters
+ ----------
+ lambda_factor: Optional[pd.NonNegativeFloat], default: 0.7
+ Lambda value within [0,1]
+
+ mu_factor: Optional[pd.NonNegativeFloat], default: 0.71
+ Mu value within [0,1]
+
+ iterations: Optional[pd.NonNegativeInt], default: 5
+ Number of smoothing iterations
+ """
+
+ # pylint: disable=no-member
+ lambda_factor: Optional[pd.NonNegativeFloat] = pd.Field(0.7)
+ mu_factor: Optional[pd.NonNegativeFloat] = pd.Field(0.71)
+ iterations: Optional[pd.NonNegativeInt] = pd.Field(5)
+
+ @pd.field_validator("iterations", mode="after")
+ @classmethod
+ def disable_by_zero(cls, value):
+ """Disable a quality metric in OpenFOAM by setting a specific valuesmoothing when None is set."""
+ if value is None:
+ return 0
+ return value
+
+
+class OctreeSpacing(Flow360BaseModel):
+ """
+ Helper class for octree-based meshers. Holds the base for the octree spacing and lows calculation of levels.
+ """
+
+ # pylint: disable=no-member
+ base_spacing: LengthType.Positive
+
+ @pd.model_validator(mode="before")
+ @classmethod
+ def _project_spacing_to_object(cls, input_data):
+ if isinstance(input_data, u.unyt.unyt_quantity):
+ return {"base_spacing": input_data}
+ return input_data
+
+ @pd.validate_call
+ def __getitem__(self, idx: int):
+ return self.base_spacing * (2 ** (-idx))
+
+ # pylint: disable=no-member
+ @pd.validate_call
+ def to_level(self, spacing: LengthType.Positive):
+ """
+ Can be used to check in what refinement level would the given spacing result
+ and if it is a direct match in the spacing series.
+ """
+ level = -log2(spacing / self.base_spacing)
+
+ direct_spacing = np.isclose(level, np.round(level), atol=1e-8)
+ returned_level = np.round(level) if direct_spacing else np.ceil(level)
+ return returned_level, direct_spacing
diff --git a/flow360/component/simulation/meshing_param/params.py b/flow360/component/simulation/meshing_param/params.py
index 0561940a7..06a7a9262 100644
--- a/flow360/component/simulation/meshing_param/params.py
+++ b/flow360/component/simulation/meshing_param/params.py
@@ -1,6 +1,6 @@
"""Meshing related parameters for volume and surface mesher."""
-from typing import Annotated, List, Optional, Union
+from typing import Annotated, List, Literal, Optional, Union
import pydantic as pd
from typing_extensions import Self
@@ -15,23 +15,46 @@
PassiveSpacing,
SurfaceRefinement,
)
+from flow360.component.simulation.meshing_param.meshing_specs import (
+ BetaVolumeMeshingDefaults,
+ MeshingDefaults,
+ OctreeSpacing,
+ SnappyCastellatedMeshControls,
+ SnappyQualityMetrics,
+ SnappySmoothControls,
+ SnappySnapControls,
+ SnappySurfaceMeshingDefaults,
+)
+from flow360.component.simulation.meshing_param.surface_mesh_refinements import (
+ SnappyBodyRefinement,
+ SnappyEntityRefinement,
+ SnappyRegionRefinement,
+ SnappySurfaceEdgeRefinement,
+)
from flow360.component.simulation.meshing_param.volume_params import (
AutomatedFarfield,
AxisymmetricRefinement,
RotationCylinder,
+ RotationVolume,
+ StructuredBoxRefinement,
UniformRefinement,
UserDefinedFarfield,
)
-from flow360.component.simulation.primitives import CustomVolume
-from flow360.component.simulation.unit_system import AngleType, LengthType
+from flow360.component.simulation.primitives import (
+ Box,
+ CustomVolume,
+ Cylinder,
+ SeedpointZone,
+)
+from flow360.component.simulation.unit_system import LengthType
from flow360.component.simulation.validation.validation_context import (
SURFACE_MESH,
VOLUME_MESH,
- ConditionalField,
ContextField,
get_validation_info,
)
from flow360.component.simulation.validation.validation_utils import EntityUsageMap
+from flow360.log import log
RefinementTypes = Annotated[
Union[
@@ -41,173 +64,49 @@
BoundaryLayer,
PassiveSpacing,
UniformRefinement,
+ StructuredBoxRefinement,
AxisymmetricRefinement,
],
pd.Field(discriminator="refinement_type"),
]
VolumeZonesTypes = Annotated[
- Union[RotationCylinder, AutomatedFarfield, UserDefinedFarfield, CustomVolume],
+ Union[
+ RotationVolume,
+ RotationCylinder,
+ AutomatedFarfield,
+ UserDefinedFarfield,
+ CustomVolume,
+ SeedpointZone,
+ ],
pd.Field(discriminator="type"),
]
+SurfaceRefinementTypes = Annotated[
+ Union[
+ SurfaceEdgeRefinement,
+ SurfaceRefinement,
+ ],
+ pd.Field(discriminator="refinement_type"),
+]
-class MeshingDefaults(Flow360BaseModel):
- """
- Default/global settings for meshing parameters.
-
- Example
- -------
-
- >>> fl.MeshingDefaults(
- ... surface_max_edge_length=1*fl.u.m,
- ... surface_edge_growth_rate=1.2,
- ... curvature_resolution_angle=12*fl.u.deg,
- ... boundary_layer_growth_rate=1.1,
- ... boundary_layer_first_layer_thickness=1e-5*fl.u.m
- ... )
-
- ====
- """
-
- # pylint: disable=no-member
- geometry_accuracy: Optional[LengthType.Positive] = pd.Field(
- None,
- description="The smallest length scale that will be resolved accurately by the surface meshing process. "
- "This parameter is only valid when using geometry AI."
- "It can be overridden with class: ~flow360.GeometryRefinement.",
- )
-
- ##:: Default surface edge settings
- surface_edge_growth_rate: float = ContextField(
- 1.2,
- ge=1,
- description="Growth rate of the anisotropic layers grown from the edges."
- "This can not be overridden per edge.",
- context=SURFACE_MESH,
- )
-
- ##:: Default boundary layer settings
- boundary_layer_growth_rate: float = ContextField(
- 1.2,
- description="Default growth rate for volume prism layers.",
- ge=1,
- context=VOLUME_MESH,
- )
- # pylint: disable=no-member
- boundary_layer_first_layer_thickness: Optional[LengthType.Positive] = ConditionalField(
- None,
- description="Default first layer thickness for volumetric anisotropic layers."
- " This can be overridden with :class:`~flow360.BoundaryLayer`.",
- context=VOLUME_MESH,
- ) # Truly optional if all BL faces already have first_layer_thickness
-
- number_of_boundary_layers: Optional[pd.NonNegativeInt] = pd.Field(
- None,
- description="Default number of volumetric anisotropic layers."
- " The volume mesher will automatically calculate the required"
- " no. of layers to grow the boundary layer elements to isotropic size if not specified."
- " This is only supported by the beta mesher and can not be overridden per face.",
- )
-
- planar_face_tolerance: Optional[pd.NonNegativeFloat] = pd.Field(
- DEFAULT_PLANAR_FACE_TOLERANCE,
- strict=True,
- description="Tolerance used for detecting planar faces in the input surface mesh / geometry"
- " that need to be remeshed, such as symmetry planes."
- " This tolerance is non-dimensional, and represents a distance"
- " relative to the largest dimension of the bounding box of the input surface mesh / geometry."
- " This can not be overridden per face.",
- )
-
- ##:: Default surface layer settings
- surface_max_edge_length: Optional[LengthType.Positive] = ConditionalField(
- None,
- description="Default maximum edge length for surface cells."
- " This can be overridden with :class:`~flow360.SurfaceRefinement`.",
- context=SURFACE_MESH,
- )
-
- surface_max_aspect_ratio: Optional[pd.PositiveFloat] = ConditionalField(
- 10.0,
- description="Maximum aspect ratio for surface cells for the GAI surface mesher."
- " This cannot be overridden per face",
- context=SURFACE_MESH,
- )
-
- surface_max_adaptation_iterations: Optional[pd.NonNegativeInt] = ConditionalField(
- 50,
- description="Maximum adaptation iterations for the GAI surface mesher.",
- context=SURFACE_MESH,
- )
-
- curvature_resolution_angle: Optional[AngleType.Positive] = ContextField(
- 12 * u.deg,
- description=(
- "Default maximum angular deviation in degrees. This value will restrict:"
- " 1. The angle between a cell’s normal and its underlying surface normal."
- " 2. The angle between a line segment’s normal and its underlying curve normal."
- " This can not be overridden per face."
- ),
- context=SURFACE_MESH,
- )
-
- preserve_thin_geometry: Optional[bool] = pd.Field(
- False,
- description="Flag to specify whether thin geometry features with thickness roughly equal "
- + "to geometry_accuracy should be resolved accurately during the surface meshing process."
- + "This can be overridden with class: ~flow360.GeometryRefinement",
- )
-
- @pd.field_validator("number_of_boundary_layers", mode="after")
- @classmethod
- def invalid_number_of_boundary_layers(cls, value):
- """Ensure number of boundary layers is not specified"""
- validation_info = get_validation_info()
-
- if validation_info is None:
- return value
-
- if value is not None and not validation_info.is_beta_mesher:
- raise ValueError("Number of boundary layers is only supported by the beta mesher.")
- return value
-
- @pd.field_validator("geometry_accuracy", mode="after")
- @classmethod
- def invalid_geometry_accuracy(cls, value):
- """Ensure geometry accuracy is not specified when GAI is not used"""
- validation_info = get_validation_info()
-
- if validation_info is None:
- return value
-
- if value is not None and not validation_info.use_geometry_AI:
- raise ValueError("Geometry accuracy is only supported when geometry AI is used.")
-
- if value is None and validation_info.use_geometry_AI:
- raise ValueError("Geometry accuracy is required when geometry AI is used.")
- return value
-
- @pd.field_validator(
- "surface_max_aspect_ratio",
- "surface_max_adaptation_iterations",
- "preserve_thin_geometry",
- mode="after",
- )
- @classmethod
- def invalid_geometry_ai_features(cls, value, info):
- """Ensure GAI features are not specified when GAI is not used"""
- validation_info = get_validation_info()
-
- if validation_info is None:
- return value
-
- # pylint: disable=unsubscriptable-object
- default_value = cls.model_fields[info.field_name].default
- if value != default_value and not validation_info.use_geometry_AI:
- raise ValueError(f"{info.field_name} is only supported when geometry AI is used.")
+SnappySurfaceRefinementTypes = Annotated[
+ Union[
+ SnappyBodyRefinement, SnappySurfaceEdgeRefinement, SnappyRegionRefinement, UniformRefinement
+ ],
+ pd.Field(discriminator="refinement_type"),
+]
- return value
+VolumeRefinementTypes = Annotated[
+ Union[
+ UniformRefinement,
+ AxisymmetricRefinement,
+ BoundaryLayer,
+ PassiveSpacing,
+ StructuredBoxRefinement,
+ ],
+ pd.Field(discriminator="refinement_type"),
+]
class MeshingParams(Flow360BaseModel):
@@ -242,6 +141,7 @@ class MeshingParams(Flow360BaseModel):
====
"""
+ type_name: Literal["MeshingParams"] = pd.Field("MeshingParams", frozen=True)
refinement_factor: Optional[pd.PositiveFloat] = pd.Field(
default=1,
description="All spacings in refinement regions"
@@ -249,6 +149,7 @@ class MeshingParams(Flow360BaseModel):
+ " finer mesh where r is the refinement_factor value.",
)
+ # pylint: disable=duplicate-code
gap_treatment_strength: Optional[float] = ContextField(
default=0,
ge=0,
@@ -283,14 +184,28 @@ def _check_volume_zones_has_farfied(cls, v):
# User did not put anything in volume_zones so may not want to use volume meshing
return v
- total_farfield = sum(
- isinstance(volume_zone, (AutomatedFarfield, UserDefinedFarfield)) for volume_zone in v
+ total_automated_farfield = sum(
+ isinstance(volume_zone, AutomatedFarfield) for volume_zone in v
)
- if total_farfield == 0:
- raise ValueError("Farfield zone is required in `volume_zones`.")
+ total_user_defined_farfield = sum(
+ isinstance(volume_zone, UserDefinedFarfield) for volume_zone in v
+ )
+ total_custom_volume = sum(isinstance(volume_zone, CustomVolume) for volume_zone in v)
+
+ if total_custom_volume:
+ total_user_defined_farfield = 0
+ log.warning(
+ "When using CustomVolume or SeedpointZone the UserDefinedFarfield will be ignored."
+ )
- if total_farfield > 1:
- raise ValueError("Only one farfield zone is allowed in `volume_zones`.")
+ if total_automated_farfield > 1:
+ raise ValueError("Only one AutomatedFarfield zone is allowed in `volume_zones`.")
+
+ if total_user_defined_farfield > 1:
+ raise ValueError("Only one UserDefinedFarfield zone is allowed in `volume_zones`.")
+
+ if (total_automated_farfield + total_user_defined_farfield + total_custom_volume) == 0:
+ raise ValueError("Farfield zone is required in `volume_zones`.")
return v
@@ -327,12 +242,20 @@ def _check_no_reused_volume_entities(self) -> Self:
| UniformRefinement | YES | NO | NO |
+------------------------+------------------------+------------------------+------------------------+
+ +------------------------+------------------------+------------------------+
+ | |StructuredBoxRefinement | UniformRefinement |
+ +------------------------+------------------------+------------------------+
+ |StructuredBoxRefinement | NO | -- |
+ +------------------------+------------------------+------------------------+
+ | UniformRefinement | NO | NO |
+ +------------------------+------------------------+------------------------+
+
"""
usage = EntityUsageMap()
for volume_zone in self.volume_zones if self.volume_zones is not None else []:
- if isinstance(volume_zone, RotationCylinder):
+ if isinstance(volume_zone, (RotationVolume, RotationCylinder)):
# pylint: disable=protected-access
_ = [
usage.add_entity_usage(item, volume_zone.type)
@@ -340,7 +263,10 @@ def _check_no_reused_volume_entities(self) -> Self:
]
for refinement in self.refinements if self.refinements is not None else []:
- if isinstance(refinement, (UniformRefinement, AxisymmetricRefinement)):
+ if isinstance(
+ refinement,
+ (UniformRefinement, AxisymmetricRefinement, StructuredBoxRefinement),
+ ):
# pylint: disable=protected-access
_ = [
usage.add_entity_usage(item, refinement.refinement_type)
@@ -350,9 +276,10 @@ def _check_no_reused_volume_entities(self) -> Self:
error_msg = ""
for entity_type, entity_model_map in usage.dict_entity.items():
for entity_info in entity_model_map.values():
- if len(entity_info["model_list"]) == 1 or sorted(
- entity_info["model_list"]
- ) == sorted(["RotationCylinder", "UniformRefinement"]):
+ if len(entity_info["model_list"]) == 1 or sorted(entity_info["model_list"]) in [
+ sorted(["RotationCylinder", "UniformRefinement"]),
+ sorted(["RotationVolume", "UniformRefinement"]),
+ ]:
# RotationCylinder and UniformRefinement are allowed to be used together
continue
@@ -382,3 +309,345 @@ def automated_farfield_method(self):
if isinstance(zone, AutomatedFarfield):
return zone.method
return None
+
+
+class SnappySurfaceMeshingParams(Flow360BaseModel):
+ """
+ Parameters for snappyHexMesh surface meshing.
+ """
+
+ type_name: Literal["SnappySurfaceMeshingParams"] = pd.Field(
+ "SnappySurfaceMeshingParams", frozen=True
+ )
+ defaults: SnappySurfaceMeshingDefaults = pd.Field()
+ quality_metrics: SnappyQualityMetrics = pd.Field(SnappyQualityMetrics())
+ snap_controls: SnappySnapControls = pd.Field(SnappySnapControls())
+ castellated_mesh_controls: SnappyCastellatedMeshControls = pd.Field(
+ SnappyCastellatedMeshControls()
+ )
+ smooth_controls: Optional[SnappySmoothControls] = pd.Field(None)
+ refinements: Optional[List[SnappySurfaceRefinementTypes]] = pd.Field(None)
+ base_spacing: Optional[OctreeSpacing] = pd.Field(None)
+
+ @pd.model_validator(mode="after")
+ def _check_body_refinements_w_defaults(self):
+ # set body refinements
+ # pylint: disable=no-member
+ if self.refinements is None:
+ return self
+ for refinement in self.refinements:
+ if isinstance(refinement, SnappyBodyRefinement):
+ if refinement.min_spacing is None and refinement.max_spacing is None:
+ continue
+ if refinement.min_spacing is None and self.defaults.min_spacing.to(
+ "m"
+ ) > refinement.max_spacing.to("m"):
+ raise ValueError(
+ "Default minimum spacing is higher that refinement maximum spacing"
+ + "and minimum spacing is not provided."
+ )
+ if refinement.max_spacing is None and self.defaults.max_spacing.to(
+ "m"
+ ) < refinement.min_spacing.to("m"):
+ raise ValueError(
+ "Default maximum spacing is lower that refinement minimum spacing"
+ + "and maximum spacing is not provided."
+ )
+ return self
+
+ @pd.model_validator(mode="after")
+ def _check_uniform_refinement_entities(self):
+ # pylint: disable=no-member
+ if self.refinements is None:
+ return self
+ for refinement in self.refinements:
+ if isinstance(refinement, UniformRefinement):
+ for entity in refinement.entities.stored_entities:
+ if isinstance(entity, Box) and entity.angle_of_rotation.to("deg") != 0 * u.deg:
+ raise ValueError(
+ "UniformRefinement for snappy accepts only Boxes with axes aligned"
+ + " with the global coordinate system (angle_of_rotation=0)."
+ )
+ if isinstance(entity, Cylinder) and entity.inner_radius.to("m") != 0 * u.m:
+ raise ValueError(
+ "UniformRefinement for snappy accepts only full cylinders (where inner_radius = 0)."
+ )
+
+ return self
+
+ @pd.model_validator(mode="after")
+ def _check_sizing_against_octree_series(self):
+
+ if self.base_spacing is None:
+ return self
+
+ def check_spacing(spacing, location):
+ # pylint: disable=no-member
+ lvl, close = self.base_spacing.to_level(spacing)
+ spacing_unit = spacing.units
+ if not close:
+ closest_spacing = self.base_spacing[lvl]
+ msg = f"The spacing of {spacing:.4g} spcified in {location} will be cast to the first lower refinement"
+ msg += f" in the octree series which is {closest_spacing.to(spacing_unit):.4g}."
+ log.warning(msg)
+
+ # pylint: disable=no-member
+ check_spacing(self.defaults.min_spacing, "defaults")
+ check_spacing(self.defaults.max_spacing, "defaults")
+
+ if self.refinements is not None:
+ # pylint: disable=not-an-iterable
+ for refinement in self.refinements:
+ if isinstance(refinement, SnappyEntityRefinement):
+ if refinement.min_spacing is not None:
+ check_spacing(refinement.min_spacing, type(refinement).__name__)
+ if refinement.max_spacing is not None:
+ check_spacing(refinement.max_spacing, type(refinement).__name__)
+ if refinement.proximity_spacing is not None:
+ check_spacing(refinement.proximity_spacing, type(refinement).__name__)
+ if isinstance(refinement, SnappySurfaceEdgeRefinement):
+ if refinement.distances is not None:
+ for spacing in refinement.spacing:
+ check_spacing(spacing, type(refinement).__name__)
+ else:
+ check_spacing(refinement.spacing, type(refinement).__name__)
+ if isinstance(refinement, UniformRefinement):
+ check_spacing(refinement.spacing, type(refinement).__name__)
+
+ return self
+
+ @pd.field_validator("base_spacing", mode="after")
+ @classmethod
+ def _set_default_base_spacing(cls, base_spacing):
+ info = get_validation_info()
+ if (info is None) or (base_spacing is not None) or (info.project_length_unit is None):
+ return base_spacing
+
+ # pylint: disable=no-member
+ base_spacing = 1 * LengthType.validate(info.project_length_unit)
+ return OctreeSpacing(base_spacing=base_spacing)
+
+
+class BetaVolumeMeshingParams(Flow360BaseModel):
+ """
+ Volume meshing parameters.
+ """
+
+ type_name: Literal["BetaVolumeMeshingParams"] = pd.Field("BetaVolumeMeshingParams", frozen=True)
+ defaults: BetaVolumeMeshingDefaults = pd.Field()
+ refinement_factor: Optional[pd.PositiveFloat] = pd.Field(
+ default=1,
+ description="All spacings in refinement regions"
+ + "and first layer thickness will be adjusted to generate `r`-times"
+ + " finer mesh where r is the refinement_factor value.",
+ )
+
+ refinements: List[VolumeRefinementTypes] = pd.Field(
+ default=[],
+ description="Additional fine-tunning for refinements on top of the global settings",
+ )
+
+ planar_face_tolerance: pd.NonNegativeFloat = pd.Field(
+ DEFAULT_PLANAR_FACE_TOLERANCE,
+ description="Tolerance used for detecting planar faces in the input surface mesh"
+ " that need to be remeshed, such as symmetry planes."
+ " This tolerance is non-dimensional, and represents a distance"
+ " relative to the largest dimension of the bounding box of the input surface mesh."
+ " This is only supported by the beta mesher and can not be overridden per face.",
+ )
+
+ gap_treatment_strength: Optional[float] = pd.Field(
+ default=0,
+ ge=0,
+ le=1,
+ description="Narrow gap treatment strength used when two surfaces are in close proximity."
+ " Use a value between 0 and 1, where 0 is no treatment and 1 is the most conservative treatment."
+ " This parameter has a global impact where the anisotropic transition into the isotropic mesh."
+ " However the impact on regions without close proximity is negligible.",
+ )
+
+
+SurfaceMeshingParams = Annotated[
+ Union[SnappySurfaceMeshingParams], pd.Field(discriminator="type_name")
+]
+VolumeMeshingParams = Annotated[Union[BetaVolumeMeshingParams], pd.Field(discriminator="type_name")]
+
+
+class ModularMeshingWorkflow(Flow360BaseModel):
+ """
+ Structure consolidating surface and volume meshing parameters.
+ """
+
+ type_name: Literal["ModularMeshingWorkflow"] = pd.Field("ModularMeshingWorkflow", frozen=True)
+ surface_meshing: Optional[SurfaceMeshingParams] = ContextField(
+ default=None, context=SURFACE_MESH
+ )
+ volume_meshing: Optional[VolumeMeshingParams] = ContextField(default=None, context=VOLUME_MESH)
+ zones: List[VolumeZonesTypes]
+
+ @pd.field_validator("zones", mode="after")
+ @classmethod
+ def _check_volume_zones_has_farfied(cls, v):
+
+ total_automated_farfield = sum(
+ isinstance(volume_zone, AutomatedFarfield) for volume_zone in v
+ )
+ total_user_defined_farfield = sum(
+ isinstance(volume_zone, UserDefinedFarfield) for volume_zone in v
+ )
+ total_custom_volume = sum(isinstance(volume_zone, CustomVolume) for volume_zone in v)
+ total_seedpoint_zone = sum(isinstance(volume_zone, SeedpointZone) for volume_zone in v)
+
+ if (total_custom_volume or total_seedpoint_zone) and total_user_defined_farfield:
+ raise ValueError(
+ "When using CustomVolume or SeedpointZone the UserDefinedFarfield will be ignored."
+ )
+
+ if total_automated_farfield > 1:
+ raise ValueError("Only one AutomatedFarfield zone is allowed in `volume_zones`.")
+
+ if total_user_defined_farfield > 1:
+ raise ValueError("Only one UserDefinedFarfield zone is allowed in `volume_zones`.")
+
+ if total_automated_farfield + total_user_defined_farfield > 1:
+ raise ValueError("Cannot use AutomatedFarfield and UserDefinedFarfield simultaneously.")
+
+ if (
+ total_user_defined_farfield
+ + total_automated_farfield
+ + total_custom_volume
+ + total_seedpoint_zone
+ ) == 0:
+ raise ValueError("At least one zone defining the farfield is required.")
+
+ if total_automated_farfield and (total_seedpoint_zone or total_custom_volume):
+ raise ValueError(
+ "SeedpointZone and CustomVolume cannot be used with AutomatedFarfield."
+ )
+
+ return v
+
+ @pd.field_validator("zones", mode="after")
+ @classmethod
+ def _check_volume_zones_have_unique_names(cls, v):
+ """Ensure there won't be duplicated volume zone names."""
+
+ if v is None:
+ return v
+ to_be_generated_volume_zone_names = set()
+ for volume_zone in v:
+ if not isinstance(volume_zone, (CustomVolume, SeedpointZone)):
+ continue
+ if volume_zone.name in to_be_generated_volume_zone_names:
+ raise ValueError(
+ f"Multiple CustomVolume or SeedpointZone with the same name `{volume_zone.name}` are not allowed."
+ )
+ to_be_generated_volume_zone_names.add(volume_zone.name)
+
+ return v
+
+ @pd.model_validator(mode="after")
+ def _check_snappy_zones(self) -> Self:
+ if isinstance(self.surface_meshing, SnappySurfaceMeshingParams):
+ if self.automated_farfield_method != "auto" and not sum(
+ isinstance(volume_zone, SeedpointZone) for volume_zone in self.zones
+ ):
+ raise ValueError(
+ "snappyHexMeshing requires at least one SeedpointZone when not using AutomatedFarfield."
+ )
+ for zone in self.zones: # pylint: disable=not-an-iterable
+ if isinstance(zone, CustomVolume):
+ raise ValueError(
+ "Volume zones with snappyHexMeshing are defined using SeedpointZones, not CustomVolumes."
+ )
+ else:
+ for zone in self.zones: # pylint: disable=not-an-iterable
+ if isinstance(zone, SeedpointZone):
+ raise ValueError("Seedpoint zones are applicable only with snappyHexMeshing.")
+
+ return self
+
+ @pd.model_validator(mode="after")
+ def _check_no_reused_volume_entities(self) -> Self:
+ """
+ Meshing entities reuse check.
+ +------------------------+------------------------+------------------------+------------------------+
+ | | RotationCylinder | AxisymmetricRefinement | UniformRefinement |
+ +------------------------+------------------------+------------------------+------------------------+
+ | RotationCylinder | NO | -- | -- |
+ +------------------------+------------------------+------------------------+------------------------+
+ | AxisymmetricRefinement | NO | NO | -- |
+ +------------------------+------------------------+------------------------+------------------------+
+ | UniformRefinement | YES | NO | NO |
+ +------------------------+------------------------+------------------------+------------------------+
+
+ +------------------------+------------------------+------------------------+
+ | |StructuredBoxRefinement | UniformRefinement |
+ +------------------------+------------------------+------------------------+
+ |StructuredBoxRefinement | NO | -- |
+ +------------------------+------------------------+------------------------+
+ | UniformRefinement | NO | NO |
+ +------------------------+------------------------+------------------------+
+
+ """
+
+ usage = EntityUsageMap()
+
+ for volume_zone in self.zones if self.zones is not None else []:
+ if isinstance(volume_zone, (RotationVolume, RotationCylinder)):
+ # pylint: disable=protected-access
+ _ = [
+ usage.add_entity_usage(item, volume_zone.type)
+ for item in volume_zone.entities._get_expanded_entities(create_hard_copy=False)
+ ]
+ # pylint: disable=no-member
+ for refinement in (
+ self.volume_meshing.refinements
+ if (self.volume_meshing is not None and self.volume_meshing.refinements is not None)
+ else []
+ ):
+ if isinstance(
+ refinement,
+ (UniformRefinement, AxisymmetricRefinement, StructuredBoxRefinement),
+ ):
+ # pylint: disable=protected-access
+ _ = [
+ usage.add_entity_usage(item, refinement.refinement_type)
+ for item in refinement.entities._get_expanded_entities(create_hard_copy=False)
+ ]
+
+ error_msg = ""
+ for entity_type, entity_model_map in usage.dict_entity.items():
+ for entity_info in entity_model_map.values():
+ if len(entity_info["model_list"]) == 1 or sorted(entity_info["model_list"]) in [
+ sorted(["RotationCylinder", "UniformRefinement"]),
+ sorted(["RotationVolume", "UniformRefinement"]),
+ ]:
+ # RotationCylinder and UniformRefinement are allowed to be used together
+ continue
+
+ model_set = set(entity_info["model_list"])
+ if len(model_set) == 1:
+ error_msg += (
+ f"{entity_type} entity `{entity_info['entity_name']}` "
+ + f"is used multiple times in `{model_set.pop()}`."
+ )
+ else:
+ model_string = ", ".join(f"`{x}`" for x in sorted(model_set))
+ error_msg += (
+ f"Using {entity_type} entity `{entity_info['entity_name']}` "
+ + f"in {model_string} at the same time is not allowed."
+ )
+
+ if error_msg:
+ raise ValueError(error_msg)
+
+ return self
+
+ @property
+ def automated_farfield_method(self):
+ """Returns the automated farfield method used."""
+ for zone in self.zones: # pylint: disable=not-an-iterable
+ if isinstance(zone, AutomatedFarfield):
+ return zone.method
+ return None
diff --git a/flow360/component/simulation/meshing_param/surface_mesh_refinements.py b/flow360/component/simulation/meshing_param/surface_mesh_refinements.py
new file mode 100644
index 000000000..a3f7f3aa3
--- /dev/null
+++ b/flow360/component/simulation/meshing_param/surface_mesh_refinements.py
@@ -0,0 +1,169 @@
+"""Reinements for surface meshing"""
+
+from abc import ABCMeta
+from typing import List, Literal, Optional, Union
+
+import pydantic as pd
+from typing_extensions import Self
+
+import flow360.component.simulation.units as u
+from flow360.component.simulation.framework.base_model import Flow360BaseModel
+from flow360.component.simulation.framework.entity_base import EntityList
+from flow360.component.simulation.primitives import SnappyBody, Surface
+from flow360.component.simulation.unit_system import AngleType, LengthType
+from flow360.log import log
+
+
+class SnappyEntityRefinement(Flow360BaseModel, metaclass=ABCMeta):
+ """
+ Base refinement for snappyHexMesh.
+ """
+
+ # pylint: disable=no-member
+ min_spacing: Optional[LengthType.Positive] = pd.Field(None)
+ max_spacing: Optional[LengthType.Positive] = pd.Field(None)
+ proximity_spacing: Optional[LengthType.Positive] = pd.Field(None)
+
+ @pd.model_validator(mode="after")
+ def _check_spacing_order(self) -> Self:
+ if self.min_spacing and self.max_spacing:
+ if self.min_spacing > self.max_spacing:
+ raise ValueError("Minimum spacing must be lower than maximum spacing.")
+ return self
+
+ @pd.model_validator(mode="after")
+ def _check_proximity_spacing(self) -> Self:
+ if self.min_spacing and self.proximity_spacing:
+ if self.proximity_spacing > self.min_spacing:
+ log.warning(
+ f"Proximity spacing ({self.proximity_spacing}) was set higher than the minimal spacing"
+ + f"({self.min_spacing}), setting proximity spacing to minimal spacing."
+ )
+ self.proximity_spacing = self.min_spacing
+ return self
+
+
+class SnappyBodyRefinement(SnappyEntityRefinement):
+ """
+ Refinement for snappyHexMesh body (searchableSurfaceWithGaps).
+
+ Parameters
+ ----------
+ gap_resolution: Optional[LengthType.NonNegative], default: None
+ """
+
+ # pylint: disable=no-member
+ refinement_type: Literal["SnappyBodyRefinement"] = pd.Field("SnappyBodyRefinement", frozen=True)
+ gap_resolution: Optional[LengthType.NonNegative] = pd.Field(None)
+ entities: EntityList[SnappyBody] = pd.Field(alias="bodies")
+
+
+class SnappyRegionRefinement(SnappyEntityRefinement):
+ """
+ Refinement for the body region in snappyHexMesh.
+
+ Parameters
+ ----------
+ min_spacing: LengthType.Positive
+ max_spacing: LengthType.Positive
+ """
+
+ # pylint: disable=no-member
+ min_spacing: LengthType.Positive = pd.Field()
+ max_spacing: LengthType.Positive = pd.Field()
+ refinement_type: Literal["SnappySurfaceRefinement"] = pd.Field(
+ "SnappySurfaceRefinement", frozen=True
+ )
+ entities: EntityList[Surface] = pd.Field(alias="regions")
+
+
+class SnappySurfaceEdgeRefinement(Flow360BaseModel):
+ """
+ Edge refinement for bodies and regions in snappyHexMesh.
+
+ Parameters
+ ----------
+ spacing: Optional[Union[LengthType.Positive, LengthType.PositiveArray]], default: None
+ Spacing on and close to the edges.
+ Defaults to default min_spacing.
+
+ distances: Optional[List[LengthType.Positive]], default: None
+ Distance from the edge where to apply the spacings.
+ Set to None to disable this metric.
+
+ min_elem: Optional[pd.NonNegativeInt], default: None
+ Minimum number of elements on the edge to apply the edge refinement.
+ Set to None to disable this metric.
+
+ min_len: Optional[LengthType.NonNegative], default: None
+ Minimum length of the edge to apply edge refinement.
+ Set to None to disable this metric.
+
+ included_angle: AngleType.Positive, default: 150°
+ If the angle between two elements is less than this value, the edge is extracted as a feature.
+
+ bodies: Optional[List[SnappyBody]], default: None
+ regions: Optional[EntityList[Surface]], default: None
+
+ retain_on_smoothing: Optional[bool], default: True
+ Maintain the edge when smoothing is applied.
+ Set to None to disable this metric.
+ """
+
+ # pylint: disable=no-member
+ refinement_type: Literal["SnappySurfaceEdgeRefinement"] = pd.Field(
+ "SnappySurfaceEdgeRefinement", frozen=True
+ )
+ spacing: Optional[Union[LengthType.PositiveArray, LengthType.Positive]] = pd.Field(None)
+ distances: Optional[LengthType.PositiveArray] = pd.Field(None)
+ min_elem: Optional[pd.NonNegativeInt] = pd.Field(None)
+ min_len: Optional[LengthType.NonNegative] = pd.Field(None)
+ included_angle: AngleType.Positive = pd.Field(150 * u.deg)
+ bodies: Optional[EntityList[SnappyBody]] = pd.Field(None)
+ regions: Optional[EntityList[Surface]] = pd.Field(None)
+ retain_on_smoothing: Optional[bool] = pd.Field(True)
+
+ @pd.model_validator(mode="after")
+ def _check_spacing_format(self) -> Self:
+ distances_state = None
+ spacing_state = None
+ if self.distances is not None:
+ distances_state = (True, len(self.distances))
+ else:
+ distances_state = (False, 0)
+
+ try:
+ spacing_state = (True, len(self.spacing))
+ except TypeError:
+ # spacing is a scalar
+ spacing_state = (False, 1)
+
+ if (
+ distances_state[0] and spacing_state[0] and (spacing_state[1] != distances_state[1])
+ ) or (distances_state[0] is not spacing_state[0]):
+ raise ValueError(
+ f"When using a distance spacing specification both spacing ({self.spacing}) and distances"
+ + f"({self.distances}) fields must be arrays and the same length."
+ )
+ return self
+
+ @pd.field_validator("spacing", "distances", mode="after")
+ @classmethod
+ def _check_spacings_increasing(cls, value):
+ if value is not None:
+ if isinstance(value.tolist(), List) and (sorted(value.tolist()) != value.tolist()):
+ raise ValueError("Spacings and distances must be increasing arrays.")
+ return value
+
+ @pd.field_validator("spacing", "distances", mode="before")
+ @classmethod
+ def _convert_list_to_unyt_array(cls, value):
+ if isinstance(value, List):
+ return u.unyt.unyt_array(value)
+ return value
+
+ @pd.model_validator(mode="after")
+ def _check_entity_lists(self) -> Self:
+ if self.bodies is None and self.regions is None:
+ raise ValueError("At least one body or region must be specified.")
+ return self
diff --git a/flow360/component/simulation/meshing_param/volume_params.py b/flow360/component/simulation/meshing_param/volume_params.py
index 5062420fa..b3cd48c69 100644
--- a/flow360/component/simulation/meshing_param/volume_params.py
+++ b/flow360/component/simulation/meshing_param/volume_params.py
@@ -6,10 +6,12 @@
from typing import Literal, Optional
import pydantic as pd
+from typing_extensions import deprecated
from flow360.component.simulation.framework.base_model import Flow360BaseModel
from flow360.component.simulation.framework.entity_base import EntityList
from flow360.component.simulation.primitives import (
+ AxisymmetricBody,
Box,
Cylinder,
GenericVolume,
@@ -17,6 +19,9 @@
Surface,
)
from flow360.component.simulation.unit_system import LengthType
+from flow360.component.simulation.validation.validation_context import (
+ get_validation_info,
+)
from flow360.component.simulation.validation.validation_utils import (
check_deleted_surface_in_entity_list,
)
@@ -45,9 +50,67 @@ class UniformRefinement(Flow360BaseModel):
)
# pylint: disable=no-member
spacing: LengthType.Positive = pd.Field(description="The required refinement spacing.")
+ project_to_surface: Optional[bool] = pd.Field(True)
+
+
+class StructuredBoxRefinement(Flow360BaseModel):
+ """
+ - The mesh inside the :class:`StructuredBoxRefinement` is semi-structured.
+ - The :class:`StructuredBoxRefinement` cannot enclose/intersect with other objects.
+ - The spacings along the three box axes can be adjusted independently.
+
+ Example
+ -------
+
+ >>> StructuredBoxRefinement(
+ ... entities=[
+ ... Box.from_principal_axes(
+ ... name="boxRefinement",
+ ... center=(0, 1, 1) * fl.u.cm,
+ ... size=(1, 2, 1) * fl.u.cm,
+ ... axes=((2, 2, 0), (-2, 2, 0)),
+ ... )
+ ... ],
+ ... spacing_axis1=7.5*u.cm,
+ ... spacing_axis2=10*u.cm,
+ ... spacing_normal=15*u.cm,
+ ... )
+ ====
+ """
+ # pylint: disable=no-member
+ # pylint: disable=too-few-public-methods
+ name: Optional[str] = pd.Field("StructuredBoxRefinement")
+ refinement_type: Literal["StructuredBoxRefinement"] = pd.Field(
+ "StructuredBoxRefinement", frozen=True
+ )
+ entities: EntityList[Box] = pd.Field()
-class CylindricalRefinementBase(Flow360BaseModel, metaclass=ABCMeta):
+ spacing_axis1: LengthType.Positive = pd.Field(
+ description="Spacing along the first axial direction."
+ )
+ spacing_axis2: LengthType.Positive = pd.Field(
+ description="Spacing along the second axial direction."
+ )
+ spacing_normal: LengthType.Positive = pd.Field(
+ description="Spacing along the normal axial direction."
+ )
+
+ @pd.model_validator(mode="after")
+ def _validate_only_in_beta_mesher(self):
+ """
+ Ensure that StructuredBoxRefinement objects are only processed with the beta mesher.
+ """
+ validation_info = get_validation_info()
+ if validation_info is None:
+ return self
+ if validation_info.is_beta_mesher:
+ return self
+
+ raise ValueError("`StructuredBoxRefinement` is only supported with the beta mesher.")
+
+
+class AxisymmetricRefinementBase(Flow360BaseModel, metaclass=ABCMeta):
"""Base class for all refinements that requires spacing in axial, radial and circumferential directions."""
# pylint: disable=no-member
@@ -60,7 +123,7 @@ class CylindricalRefinementBase(Flow360BaseModel, metaclass=ABCMeta):
)
-class AxisymmetricRefinement(CylindricalRefinementBase):
+class AxisymmetricRefinement(AxisymmetricRefinementBase):
"""
- The mesh inside the :class:`AxisymmetricRefinement` is semi-structured.
- The :class:`AxisymmetricRefinement` cannot enclose/intersect with other objects.
@@ -89,17 +152,25 @@ class AxisymmetricRefinement(CylindricalRefinementBase):
entities: EntityList[Cylinder] = pd.Field()
-class RotationCylinder(CylindricalRefinementBase):
+class RotationVolume(AxisymmetricRefinementBase):
"""
- - The mesh on :class:`RotationCylinder` is guaranteed to be concentric.
- - The :class:`RotationCylinder` is designed to enclose other objects, but it can’t intersect with other objects.
- - Users could create a donut-shape :class:`RotationCylinder` and put their stationary centerbody in the middle.
- - This type of volume zone can be used to generate volume zone compatible with :class:`~flow360.Rotation` model.
+ Creates a rotation volume mesh using cylindrical or axisymmetric body entities.
+
+ - The mesh on :class:`RotationVolume` is guaranteed to be concentric.
+ - The :class:`RotationVolume` is designed to enclose other objects, but it can't intersect with other objects.
+ - Users can create a donut-shaped :class:`RotationVolume` and put their stationary centerbody in the middle.
+ - This type of volume zone can be used to generate volume zones compatible with :class:`~flow360.Rotation` model.
+ - Supports both :class:`Cylinder` and :class:`AxisymmetricBody` entities for defining the rotation volume geometry.
+
+ .. note::
+ The deprecated :class:`RotationCylinder` class is maintained for backward compatibility
+ but only accepts :class:`Cylinder` entities. New code should use :class:`RotationVolume`.
Example
-------
+ Using a Cylinder entity:
- >>> fl.RotationCylinder(
+ >>> fl.RotationVolume(
... name="RotationCylinder",
... spacing_axial=0.5*fl.u.m,
... spacing_circumferential=0.3*fl.u.m,
@@ -107,20 +178,41 @@ class RotationCylinder(CylindricalRefinementBase):
... entities=cylinder
... )
- ====
+ Using an AxisymmetricBody entity:
+
+ >>> fl.RotationVolume(
+ ... name="RotationConeFrustum",
+ ... spacing_axial=0.5*fl.u.m,
+ ... spacing_circumferential=0.3*fl.u.m,
+ ... spacing_radial=1.5*fl.u.m,
+ ... entities=axisymmetric_body
+ ... )
+
+ With enclosed entities:
+
+ >>> fl.RotationVolume(
+ ... name="RotationVolume",
+ ... spacing_axial=0.5*fl.u.m,
+ ... spacing_circumferential=0.3*fl.u.m,
+ ... spacing_radial=1.5*fl.u.m,
+ ... entities=outer_cylinder,
+ ... enclosed_entities=[inner_cylinder, surface]
+ ... )
"""
# Note: Please refer to
# Note: https://www.notion.so/flexcompute/Python-model-design-document-
# Note: 78d442233fa944e6af8eed4de9541bb1?pvs=4#c2de0b822b844a12aa2c00349d1f68a3
- type: Literal["RotationCylinder"] = pd.Field("RotationCylinder", frozen=True)
- name: Optional[str] = pd.Field("Rotation cylinder", description="Name to display in the GUI.")
- entities: EntityList[Cylinder] = pd.Field()
- enclosed_entities: Optional[EntityList[Cylinder, Surface]] = pd.Field(
+ type: Literal["RotationVolume"] = pd.Field("RotationVolume", frozen=True)
+ name: Optional[str] = pd.Field("Rotation Volume", description="Name to display in the GUI.")
+ entities: EntityList[Cylinder, AxisymmetricBody] = pd.Field()
+ enclosed_entities: Optional[EntityList[Cylinder, Surface, AxisymmetricBody, Box]] = pd.Field(
None,
- description="Entities enclosed by :class:`RotationCylinder`. "
- + "Can be `Surface` and/or other :class:`~flow360.Cylinder` (s).",
+ description="Entities enclosed by :class:`RotationVolume`. "
+ "Can be `Surface` and/or other :class:`~flow360.Cylinder`(s)"
+ "and/or other :class:`~flow360.AxisymmetricBody`(s)"
+ "and/or other :class:`~flow360.Box`(s)",
)
@pd.field_validator("entities", mode="after")
@@ -135,7 +227,7 @@ def _validate_single_instance_in_entity_list(cls, values):
# pylint: disable=protected-access
if len(values._get_expanded_entities(create_hard_copy=False)) > 1:
raise ValueError(
- "Only single instance is allowed in entities for each RotationCylinder."
+ "Only single instance is allowed in entities for each `RotationVolume`."
)
return values
@@ -147,17 +239,63 @@ def _validate_cylinder_name_length(cls, values):
limitation of all data structure names and labels in CGNS format.
The current prefix is 'rotatingBlock-' with 14 characters.
"""
+ validation_info = get_validation_info()
+ if validation_info is None:
+ return values
+ if validation_info.is_beta_mesher:
+ return values
cgns_max_zone_name_length = 32
max_cylinder_name_length = cgns_max_zone_name_length - len("rotatingBlock-")
for entity in values.stored_entities:
- if len(entity.name) > max_cylinder_name_length:
+ if isinstance(entity, Cylinder) and len(entity.name) > max_cylinder_name_length:
raise ValueError(
- f"The name ({entity.name}) of `Cylinder` entity in `RotationCylinder` "
+ f"The name ({entity.name}) of `Cylinder` entity in `RotationVolume` "
+ f"exceeds {max_cylinder_name_length} characters limit."
)
return values
+ @pd.field_validator("enclosed_entities", mode="after")
+ @classmethod
+ def _validate_enclosed_box_only_in_beta_mesher(cls, values):
+ """
+ Check the name length for the cylinder entities due to the 32-character
+ limitation of all data structure names and labels in CGNS format.
+ The current prefix is 'rotatingBlock-' with 14 characters.
+ """
+ validation_info = get_validation_info()
+ if validation_info is None:
+ return values
+ if validation_info.is_beta_mesher:
+ return values
+
+ for entity in values.stored_entities:
+ if isinstance(entity, Box):
+ raise ValueError(
+ "`Box` entity in `RotationVolume.enclosed_entities` is only supported with the beta mesher."
+ )
+
+ return values
+
+ @pd.field_validator("entities", mode="after")
+ @classmethod
+ def _validate_axisymmetric_only_in_beta_mesher(cls, values):
+ """
+ Ensure that axisymmetric RotationVolumes are only processed with the beta mesher.
+ """
+ validation_info = get_validation_info()
+ if validation_info is None:
+ return values
+ if validation_info.is_beta_mesher:
+ return values
+
+ for entity in values.stored_entities:
+ if isinstance(entity, AxisymmetricBody):
+ raise ValueError(
+ "`AxisymmetricBody` entity for `RotationVolume` is only supported with the beta mesher."
+ )
+ return values
+
@pd.field_validator("enclosed_entities", mode="after")
@classmethod
def ensure_surface_existence(cls, value):
@@ -167,6 +305,42 @@ def ensure_surface_existence(cls, value):
return check_deleted_surface_in_entity_list(value)
+@deprecated(
+ "The `RotationCylinder` class is deprecated! Use `RotationVolume`,"
+ "which supports both `Cylinder` and `AxisymmetricBody` entities instead."
+)
+class RotationCylinder(RotationVolume):
+ """
+ .. deprecated::
+ Use :class:`RotationVolume` instead. This class is maintained for backward
+ compatibility but will be removed in a future version.
+
+ RotationCylinder creates a rotation volume mesh using cylindrical entities.
+
+ - The mesh on :class:`RotationCylinder` is guaranteed to be concentric.
+ - The :class:`RotationCylinder` is designed to enclose other objects, but it can't intersect with other objects.
+ - Users could create a donut-shape :class:`RotationCylinder` and put their stationary centerbody in the middle.
+ - This type of volume zone can be used to generate volume zone compatible with :class:`~flow360.Rotation` model.
+
+ .. note::
+ :class:`RotationVolume` now supports both :class:`Cylinder` and :class:`AxisymmetricBody` entities.
+ Please migrate to using :class:`RotationVolume` directly.
+
+ Example
+ -------
+ >>> fl.RotationCylinder(
+ ... name="RotationCylinder",
+ ... spacing_axial=0.5*fl.u.m,
+ ... spacing_circumferential=0.3*fl.u.m,
+ ... spacing_radial=1.5*fl.u.m,
+ ... entities=cylinder
+ ... )
+ """
+
+ type: Literal["RotationCylinder"] = pd.Field("RotationCylinder", frozen=True)
+ entities: EntityList[Cylinder] = pd.Field()
+
+
class AutomatedFarfield(Flow360BaseModel):
"""
Settings for automatic farfield volume zone generation.
@@ -195,7 +369,9 @@ class AutomatedFarfield(Flow360BaseModel):
""",
)
private_attribute_entity: GenericVolume = pd.Field(
- GenericVolume(name="__farfield_zone_name_not_properly_set_yet"), frozen=True, exclude=True
+ GenericVolume(name="__farfield_zone_name_not_properly_set_yet"),
+ frozen=True,
+ exclude=True,
)
@property
@@ -232,5 +408,6 @@ class UserDefinedFarfield(Flow360BaseModel):
====
"""
+ # pylint: disable=no-member
type: Literal["UserDefinedFarfield"] = pd.Field("UserDefinedFarfield", frozen=True)
- name: Optional[str] = pd.Field(None)
+ name: Optional[str] = pd.Field("farfield")
diff --git a/flow360/component/simulation/models/volume_models.py b/flow360/component/simulation/models/volume_models.py
index 69a36ccbe..675af0ad2 100644
--- a/flow360/component/simulation/models/volume_models.py
+++ b/flow360/component/simulation/models/volume_models.py
@@ -68,6 +68,7 @@
Cylinder,
EntityListWithCustomVolume,
GenericVolume,
+ SeedpointZone,
)
from flow360.component.simulation.unit_system import (
AngleType,
@@ -1412,10 +1413,12 @@ class Rotation(Flow360BaseModel):
name: Optional[str] = pd.Field("Rotation", description="Name of the `Rotation` model.")
type: Literal["Rotation"] = pd.Field("Rotation", frozen=True)
- entities: EntityListWithCustomVolume[GenericVolume, Cylinder, CustomVolume] = pd.Field(
- alias="volumes",
- description="The entity list for the `Rotation` model. "
- + "The entity should be :class:`Cylinder` or :class:`GenericVolume` type.",
+ entities: EntityListWithCustomVolume[GenericVolume, Cylinder, CustomVolume, SeedpointZone] = (
+ pd.Field(
+ alias="volumes",
+ description="The entity list for the `Rotation` model. "
+ + "The entity should be :class:`Cylinder` or :class:`GenericVolume` type.",
+ )
)
# TODO: Add test for each of the spec specification.
@@ -1423,7 +1426,7 @@ class Rotation(Flow360BaseModel):
discriminator="type_name",
description="The angular velocity or rotation angle as a function of time.",
)
- parent_volume: Optional[Union[GenericVolume, Cylinder, CustomVolume]] = pd.Field(
+ parent_volume: Optional[Union[GenericVolume, Cylinder, CustomVolume, SeedpointZone]] = pd.Field(
None,
description="The parent rotating entity in a nested rotation case."
+ "The entity should be :class:`Cylinder` or :class:`GenericVolume` type.",
@@ -1513,12 +1516,15 @@ class PorousMedium(Flow360BaseModel):
name: Optional[str] = pd.Field("Porous medium", description="Name of the `PorousMedium` model.")
type: Literal["PorousMedium"] = pd.Field("PorousMedium", frozen=True)
- entities: EntityListWithCustomVolume[GenericVolume, Box, CustomVolume] = pd.Field(
- alias="volumes",
- description="The entity list for the `PorousMedium` model. "
- + "The entity should be defined by :class:`Box` or zones from the geometry/volume mesh."
- + "The axes of entity must be specified to serve as the the principle axes of the "
- + "porous medium material model.",
+ entities: EntityListWithCustomVolume[GenericVolume, Box, CustomVolume, SeedpointZone] = (
+ pd.Field(
+ alias="volumes",
+ description="The entity list for the `PorousMedium` model. "
+ + "The entity should be defined by :class:`Box`, zones from the geometry/volume mesh or"
+ + "by :class:`SeedpointZone` when using snappyHexMeshing."
+ + "The axes of entity must be specified to serve as the the principle axes of the "
+ + "porous medium material model.",
+ )
)
darcy_coefficient: InverseAreaType.Point = pd.Field(
diff --git a/flow360/component/simulation/primitives.py b/flow360/component/simulation/primitives.py
index dc19ea2ef..d1800d4b0 100644
--- a/flow360/component/simulation/primitives.py
+++ b/flow360/component/simulation/primitives.py
@@ -34,17 +34,21 @@
get_validation_info,
)
from flow360.component.types import Axis
+from flow360.component.utils import _naming_pattern_handler
BOUNDARY_FULL_NAME_WHEN_NOT_FOUND = "This boundary does not exist!!!"
-def _get_boundary_full_name(surface_name: str, volume_mesh_meta: dict[str, dict]) -> str:
- """Ideally volume_mesh_meta should be a pydantic model.
+def _get_generated_boundary_names(surface_name: str, volume_mesh_meta: dict[str, dict]) -> list:
+ """
+
+ Returns all the boundaries that are eventually generated by name matching in the volume mesh metadata.
+
+ May return multiple boundaries when the original one is split into multiple boundaries.
- TODO: Note that the same surface_name may appear in different blocks. E.g.
- `farFieldBlock/slipWall`, and `plateBlock/slipWall`. Currently the mesher does not support splitting boundary into
- blocks but we will need to support this someday.
"""
+ full_boundary_names = []
+
for zone_name, zone_meta in volume_mesh_meta["zones"].items():
for existing_boundary_name in zone_meta["boundaryNames"]:
pattern = re.escape(zone_name) + r"/(.*)"
@@ -52,10 +56,13 @@ def _get_boundary_full_name(surface_name: str, volume_mesh_meta: dict[str, dict]
if (
match is not None and match.group(1) == surface_name
) or existing_boundary_name == surface_name:
- return existing_boundary_name
+ full_boundary_names.append(existing_boundary_name)
# Not found
- return BOUNDARY_FULL_NAME_WHEN_NOT_FOUND
+ if not full_boundary_names:
+ return [BOUNDARY_FULL_NAME_WHEN_NOT_FOUND]
+
+ return full_boundary_names
def _check_axis_is_orthogonal(axis_pair: Tuple[Axis, Axis]) -> Tuple[Axis, Axis]:
@@ -186,11 +193,24 @@ def _update_entity_info_with_metadata(self, volume_mesh_meta_data: dict) -> None
"""
Update parent zone name once the volume mesh is done.
"""
+ updated_boundary_names = _get_generated_boundary_names(self.name, volume_mesh_meta_data)
+
with model_attribute_unlock(self, "private_attribute_full_name"):
- self.private_attribute_full_name = _get_boundary_full_name(
- self.name, volume_mesh_meta_data
+ self.private_attribute_full_name = updated_boundary_names.pop(0)
+
+ multiplication_result = []
+ for new_boundary_name in updated_boundary_names:
+ multiplication_result.append(
+ self.copy(
+ update={
+ "name": new_boundary_name,
+ "private_attribute_full_name": new_boundary_name,
+ }
+ )
)
+ return multiplication_result if multiplication_result else None
+
@property
def full_name(self):
"""Gets the full name which includes the zone name"""
@@ -412,6 +432,62 @@ def _check_inner_radius_is_less_than_outer_radius(self) -> Self:
return self
+@final
+class AxisymmetricBody(_VolumeEntityBase):
+ """
+ :class:`AxisymmetricBody` class represents a generic body of revolution in three-dimensional space,
+ represented as a list[(Axial Position, Radial Extent)] profile polyline with arbitrary center and axial direction.
+ Expect first and last profile samples to connect to axis, i.e., have radius = 0.
+
+ Example
+ -------
+ >>> fl.AxisymmetricBody(
+ ... name="cone_frustum_body",
+ ... center=(0, 0, 0) * fl.u.inch,
+ ... axis=(0, 0, 1),
+ ... profile_curve = [(-1, 0) * fl.u.inch, (-1, 1) * fl.u.inch, (1, 2) * fl.u.inch, (1, 0) * fl.u.inch]
+ ... )
+
+ ====
+ """
+
+ private_attribute_entity_type_name: Literal["AxisymmetricBody"] = pd.Field(
+ "AxisymmetricBody", frozen=True
+ )
+ axis: Axis = pd.Field(description="The axis of the body of revolution.")
+ # pylint: disable=no-member
+ center: LengthType.Point = pd.Field(description="The center point of the body of revolution.")
+ profile_curve: List[LengthType.Pair] = pd.Field(
+ description="The (Axial, Radial) profile of the body of revolution."
+ )
+
+ private_attribute_id: str = pd.Field(default_factory=generate_uuid, frozen=True)
+
+ @pd.field_validator("profile_curve", mode="after")
+ @classmethod
+ def _check_radial_profile_is_positive(cls, curve):
+ first_point = curve[0]
+ if first_point[1] != 0:
+ raise ValueError(
+ f"Expect first profile sample to be (Axial, 0.0). Found invalid point: {str(first_point)}."
+ )
+
+ last_point = curve[-1]
+ if last_point[1] != 0:
+ raise ValueError(
+ f"Expect last profile sample to be (Axial, 0.0). Found invalid point: {str(last_point)}."
+ )
+
+ for profile_point in curve[1:-1]:
+ if profile_point[1] < 0:
+ raise ValueError(
+ f"Expect profile samples to be (Axial, Radial) samples with positive Radial."
+ f" Found invalid point: {str(profile_point)}."
+ )
+
+ return curve
+
+
class SurfacePrivateAttributes(Flow360BaseModel):
"""
Private attributes for Surface.
@@ -641,6 +717,66 @@ def __str__(self):
return ",".join(sorted([self.pair[0].name, self.pair[1].name]))
+class SnappyBody(EntityBase):
+ """
+ Represents a group of faces forming a body for snappyHexMesh.
+ Bodies and their regions are defined in the ASCII STL file by using the solid -> endsolid"
+ keywords with a body::region naming scheme.
+ """
+
+ private_attribute_registry_bucket_name: Literal["SurfaceGroupedEntityType"] = pd.Field(
+ "SurfaceGroupedEntityType", frozen=True
+ )
+ private_attribute_entity_type_name: Literal["SnappyBody"] = pd.Field("SnappyBody", frozen=True)
+ private_attribute_id: str = pd.Field(
+ default_factory=generate_uuid,
+ frozen=True,
+ description="Unique identifier for the entity. Used by front end to track entities and enable auto update etc.",
+ )
+
+ surfaces: List[Surface] = pd.Field()
+
+ def __getitem__(self, key: str):
+ if len(self.surfaces) == 1 and ("::" not in self.surfaces[0].name):
+ regex = _naming_pattern_handler(pattern=key)
+ else:
+ regex = _naming_pattern_handler(pattern=f"{self.name}::{key}")
+
+ matched_surfaces = [entity for entity in self.surfaces if regex.match(entity.name)]
+ if not matched_surfaces:
+ print(key)
+ raise KeyError(
+ f"No entity found in registry for parent entity: {self.name} with given name/naming pattern: '{key}'."
+ )
+ return matched_surfaces
+
+
+@final
+class SeedpointZone(_VolumeEntityBase):
+ """
+ Represents a separate zone in the mesh, defined by a point inside it.
+ To be used only with snappyHexMesh.
+ """
+
+ # pylint: disable=no-member
+ private_attribute_entity_type_name: Literal["SeedpointZone"] = pd.Field(
+ "SeedpointZone", frozen=True
+ )
+ type: Literal["SeedpointZone"] = pd.Field("SeedpointZone", frozen=True)
+ point_in_mesh: LengthType.Point = pd.Field(
+ description="Seedpoint for a main fluid zone in snappyHexMesh."
+ )
+ axes: Optional[OrthogonalAxes] = pd.Field(
+ None, description="Principal axes definition when using with PorousMedium"
+ ) # Porous media support
+ axis: Optional[Axis] = pd.Field(None) # Rotation support
+ center: Optional[LengthType.Point] = pd.Field(None, description="") # Rotation support
+ private_attribute_id: str = pd.Field(default_factory=generate_uuid, frozen=True)
+
+
+VolumeEntityTypes = Union[GenericVolume, Cylinder, Box, str]
+
+
@final
class CustomVolume(_VolumeEntityBase):
"""
diff --git a/flow360/component/simulation/simulation_params.py b/flow360/component/simulation/simulation_params.py
index 5d0ec28cf..43d93bd7a 100644
--- a/flow360/component/simulation/simulation_params.py
+++ b/flow360/component/simulation/simulation_params.py
@@ -24,10 +24,14 @@
)
from flow360.component.simulation.framework.updater import updater
from flow360.component.simulation.framework.updater_utils import Flow360Version
-from flow360.component.simulation.meshing_param.params import MeshingParams
+from flow360.component.simulation.meshing_param.params import (
+ MeshingParams,
+ ModularMeshingWorkflow,
+)
from flow360.component.simulation.meshing_param.volume_params import (
AutomatedFarfield,
RotationCylinder,
+ RotationVolume,
)
from flow360.component.simulation.models.surface_models import SurfaceModelTypes
from flow360.component.simulation.models.volume_models import (
@@ -148,7 +152,8 @@ def _init_check_unit_system(cls, **kwargs):
if kwarg_unit_system != unit_system_manager.current:
raise Flow360RuntimeError(
unit_system_inconsistent_msg(
- kwarg_unit_system.system_repr(), unit_system_manager.current.system_repr()
+ kwarg_unit_system.system_repr(),
+ unit_system_manager.current.system_repr(),
)
)
@@ -179,7 +184,9 @@ def _update_param_dict(cls, model_dict, version_to=__version__):
forward_compatibility_mode = Flow360Version(input_version) > Flow360Version(version_to)
if not forward_compatibility_mode:
model_dict = updater(
- version_from=input_version, version_to=version_to, params_as_dict=model_dict
+ version_from=input_version,
+ version_to=version_to,
+ params_as_dict=model_dict,
)
return model_dict, forward_compatibility_mode
@@ -246,9 +253,10 @@ def copy(self, update=None, **kwargs) -> _ParamModelBase:
class SimulationParams(_ParamModelBase):
"""All-in-one class for surface meshing + volume meshing + case configurations"""
- meshing: Optional[MeshingParams] = ConditionalField(
+ meshing: Optional[Union[MeshingParams, ModularMeshingWorkflow]] = ConditionalField(
None,
context=[SURFACE_MESH, VOLUME_MESH],
+ discriminator="type_name",
description="Surface and volume meshing parameters. See :class:`MeshingParams` for more details.",
)
@@ -296,7 +304,8 @@ class SimulationParams(_ParamModelBase):
# Limitations:
# 1. No per volume zone output. (single volume output)
outputs: Optional[List[OutputTypes]] = CaseField(
- None, description="Output settings. See :ref:`Outputs ` for more details."
+ None,
+ description="Output settings. See :ref:`Outputs ` for more details.",
)
##:: [INTERNAL USE ONLY] Private attributes that should not be modified manually.
@@ -325,7 +334,10 @@ def _private_set_length_unit(self, validated_mesh_unit):
@pd.validate_call
def convert_unit(
- self, value: DimensionedTypes, target_system: str, length_unit: Optional[LengthType] = None
+ self,
+ value: DimensionedTypes,
+ target_system: str,
+ length_unit: Optional[LengthType] = None,
):
"""
Converts a given value to the specified unit system.
@@ -548,23 +560,32 @@ def _update_entity_private_attrs(self, registry: EntityRegistry) -> EntityRegist
##::1. Update full names in the Surface entities with zone names
# pylint: disable=no-member
- if self.meshing is not None and self.meshing.volume_zones is not None:
- for volume in self.meshing.volume_zones:
- if isinstance(volume, AutomatedFarfield):
- _set_boundary_full_name_with_zone_name(
- registry,
- "farfield",
- volume.private_attribute_entity.name,
- )
- _set_boundary_full_name_with_zone_name(
- registry,
- "symmetric*",
- volume.private_attribute_entity.name,
- )
- if isinstance(volume, RotationCylinder):
- # pylint: disable=fixme
- # TODO: Implement this
- pass
+ if self.meshing is not None:
+ volume_zones = None
+ if isinstance(self.meshing, MeshingParams):
+ volume_zones = self.meshing.volume_zones
+ if (
+ isinstance(self.meshing, ModularMeshingWorkflow)
+ and self.meshing.volume_meshing is not None
+ ):
+ volume_zones = self.meshing.zones
+ if volume_zones is not None:
+ for volume in volume_zones:
+ if isinstance(volume, AutomatedFarfield):
+ _set_boundary_full_name_with_zone_name(
+ registry,
+ "farfield",
+ volume.private_attribute_entity.name,
+ )
+ _set_boundary_full_name_with_zone_name(
+ registry,
+ "symmetric*",
+ volume.private_attribute_entity.name,
+ )
+ if isinstance(volume, (RotationCylinder, RotationVolume)):
+ # pylint: disable=fixme
+ # TODO: Implement this
+ pass
return registry
diff --git a/flow360/component/simulation/translator/surface_meshing_translator.py b/flow360/component/simulation/translator/surface_meshing_translator.py
index 7994e6dab..622fc22ea 100644
--- a/flow360/component/simulation/translator/surface_meshing_translator.py
+++ b/flow360/component/simulation/translator/surface_meshing_translator.py
@@ -1,13 +1,38 @@
"""Surface meshing parameter translator."""
+from copy import deepcopy
from typing import List
+from unyt import unyt_array
+
from flow360.component.simulation.entity_info import GeometryEntityInfo
from flow360.component.simulation.meshing_param.edge_params import SurfaceEdgeRefinement
from flow360.component.simulation.meshing_param.face_params import SurfaceRefinement
-from flow360.component.simulation.primitives import Surface
+from flow360.component.simulation.meshing_param.meshing_specs import OctreeSpacing
+from flow360.component.simulation.meshing_param.params import (
+ MeshingParams,
+ ModularMeshingWorkflow,
+ SnappySurfaceMeshingParams,
+)
+from flow360.component.simulation.meshing_param.surface_mesh_refinements import (
+ SnappyBodyRefinement,
+ SnappyRegionRefinement,
+ SnappySurfaceEdgeRefinement,
+)
+from flow360.component.simulation.meshing_param.volume_params import (
+ AutomatedFarfield,
+ UniformRefinement,
+ UserDefinedFarfield,
+)
+from flow360.component.simulation.primitives import (
+ Box,
+ Cylinder,
+ SeedpointZone,
+ Surface,
+)
from flow360.component.simulation.simulation_params import SimulationParams
from flow360.component.simulation.translator.utils import (
+ ensure_meshing_is_specified,
preprocess_input,
translate_setting_and_apply_to_all_entities,
)
@@ -19,7 +44,6 @@
def SurfaceEdgeRefinement_to_edges(obj: SurfaceEdgeRefinement):
"""
Translate SurfaceEdgeRefinement to edges.
-
"""
if obj.method.type == "angle":
return {
@@ -48,7 +72,6 @@ def SurfaceEdgeRefinement_to_edges(obj: SurfaceEdgeRefinement):
def SurfaceRefinement_to_faces(obj: SurfaceRefinement, global_max_edge_length):
"""
Translate SurfaceRefinement to faces.
-
"""
return {
"maxEdgeLength": (
@@ -59,20 +82,407 @@ def SurfaceRefinement_to_faces(obj: SurfaceRefinement, global_max_edge_length):
}
-def legacy_mesher_json(input_params: SimulationParams):
+def remove_numerical_noise_from_spacing(spacing, spacing_system: OctreeSpacing):
"""
- Get JSON for surface meshing.
+ If the spacing is in the proximity of 1e-8 to one of the octree series spacing casts that spacing onto the series.
+ """
+ direct = spacing_system.to_level(spacing)[1]
+ if direct:
+ return spacing_system[spacing_system.to_level(spacing)[0]]
+ return spacing
+
+def apply_SnappyBodyRefinement(
+ refinement: SnappyBodyRefinement, translated, spacing_system: OctreeSpacing
+):
+ """
+ Translate SnappyBodyRefinement to bodies.
+ """
+ applicable_bodies = [entity.name for entity in refinement.entities.stored_entities]
+ for body in translated["geometry"]["bodies"]:
+ if body["bodyName"] in applicable_bodies:
+ if refinement.gap_resolution is not None:
+ body["gap"] = refinement.gap_resolution.value.item()
+ if refinement.proximity_spacing is not None:
+ body["gapSpacingReduction"] = remove_numerical_noise_from_spacing(
+ refinement.proximity_spacing, spacing_system
+ ).value.item()
+ if refinement.min_spacing is not None:
+ body["spacing"]["min"] = remove_numerical_noise_from_spacing(
+ refinement.min_spacing, spacing_system
+ ).value.item()
+ if refinement.max_spacing is not None:
+ body["spacing"]["max"] = remove_numerical_noise_from_spacing(
+ refinement.max_spacing, spacing_system
+ ).value.item()
+
+
+def get_applicable_regions_dict(refinement_regions):
+ """
+ Get regions to apply a refinement on.
+ """
+ applicable_regions = {}
+ if refinement_regions:
+ for entity in refinement_regions.stored_entities:
+ split = entity.name.split("::")
+ body = split[0]
+ if len(split) == 2:
+ region = split[1]
+ else:
+ applicable_regions[body] = None
+ continue
+
+ if body in applicable_regions:
+ applicable_regions[body].append(region)
+ else:
+ applicable_regions[body] = [region]
+
+ return applicable_regions
+
+
+def apply_SnappySurfaceEdgeRefinement(
+ refinement: SnappySurfaceEdgeRefinement, translated, defaults, spacing_system: OctreeSpacing
+):
+ """
+ Translate SnappySurfaceEdgeRefinement to bodies and regions.
+ """
+ edges = {"includedAngle": refinement.included_angle.to("degree").value.item()}
+ if refinement.min_elem is not None:
+ edges["minElem"] = refinement.min_elem
+ if refinement.min_len is not None:
+ edges["minLen"] = refinement.min_len.value.item()
+ if refinement.retain_on_smoothing is not None:
+ edges["retainOnSmoothing"] = refinement.retain_on_smoothing
+ if refinement.spacing is None:
+ edges["edgeSpacing"] = defaults.min_spacing.value.item()
+ elif isinstance(refinement.spacing, unyt_array) and isinstance(
+ refinement.distances, unyt_array
+ ):
+ edges["edgeSpacing"] = [
+ [
+ dist.value.item(),
+ remove_numerical_noise_from_spacing(spac, spacing_system).value.item(),
+ ]
+ for (dist, spac) in zip(refinement.distances, refinement.spacing)
+ ]
+ else:
+ edges["edgeSpacing"] = remove_numerical_noise_from_spacing(
+ refinement.spacing, spacing_system
+ ).value.item()
+ applicable_bodies = (
+ [entity.name for entity in refinement.bodies.stored_entities]
+ if refinement.bodies is not None
+ else []
+ )
+ applicable_regions = get_applicable_regions_dict(refinement_regions=refinement.regions)
+ for body in translated["geometry"]["bodies"]:
+ if body["bodyName"] in applicable_bodies or (
+ body["bodyName"] in applicable_regions and applicable_regions[body["bodyName"]] is None
+ ):
+ body["edges"] = edges
+ if body["bodyName"] in applicable_regions:
+ for region in body.get("regions", []):
+ if region["patchName"] in applicable_regions[body["bodyName"]]:
+ region["edges"] = edges
+
+
+def apply_SnappyRegionRefinement(
+ refinement: SnappyRegionRefinement, translated, spacing_system: OctreeSpacing
+):
+ """
+ Translate SnappyRegionRefinement to applicable regions.
+ """
+ applicable_regions = applicable_regions = get_applicable_regions_dict(
+ refinement_regions=refinement.entities
+ )
+ for body in translated["geometry"]["bodies"]:
+ if body["bodyName"] in applicable_regions:
+ for region in body.get("regions", []):
+ if region["patchName"] in applicable_regions[body["bodyName"]]:
+ if refinement.proximity_spacing is not None:
+ region["gapSpacingReduction"] = remove_numerical_noise_from_spacing(
+ refinement.proximity_spacing, spacing_system
+ ).value.item()
+
+ region["spacing"] = {
+ "min": remove_numerical_noise_from_spacing(
+ refinement.min_spacing, spacing_system
+ ).value.item(),
+ "max": remove_numerical_noise_from_spacing(
+ refinement.max_spacing, spacing_system
+ ).value.item(),
+ }
+
+
+def apply_UniformRefinement_w_snappy(
+ refinement: UniformRefinement, translated, spacing_system: OctreeSpacing
+):
+ """
+ Translate UniformRefinement to defined volumetric regions.
+ """
+ if "refinementVolumes" not in translated["geometry"]:
+ translated["geometry"]["refinementVolumes"] = []
+
+ for volume in refinement.entities.stored_entities:
+ volume_body = {
+ "spacing": remove_numerical_noise_from_spacing(
+ refinement.spacing, spacing_system
+ ).value.item(),
+ "name": volume.name,
+ }
+ if isinstance(volume, Box):
+ volume_body["type"] = "box"
+ volume_body["min"] = {
+ "x": volume.center[0].value.item() - 0.5 * volume.size[0].value.item(),
+ "y": volume.center[1].value.item() - 0.5 * volume.size[1].value.item(),
+ "z": volume.center[2].value.item() - 0.5 * volume.size[2].value.item(),
+ }
+ volume_body["max"] = {
+ "x": volume.center[0].value.item() + 0.5 * volume.size[0].value.item(),
+ "y": volume.center[1].value.item() + 0.5 * volume.size[1].value.item(),
+ "z": volume.center[2].value.item() + 0.5 * volume.size[2].value.item(),
+ }
+ elif isinstance(volume, Cylinder):
+ volume_body["type"] = "cylinder"
+ volume_body["radius"] = volume.outer_radius.value.item()
+ volume_body["point1"] = {
+ "x": volume.center[0].value.item()
+ - 0.5 * volume.axis[0] * volume.height.value.item(),
+ "y": volume.center[1].value.item()
+ - 0.5 * volume.axis[1] * volume.height.value.item(),
+ "z": volume.center[2].value.item()
+ - 0.5 * volume.axis[2] * volume.height.value.item(),
+ }
+
+ volume_body["point2"] = {
+ "x": volume.center[0].value.item()
+ + 0.5 * volume.axis[0] * volume.height.value.item(),
+ "y": volume.center[1].value.item()
+ + 0.5 * volume.axis[1] * volume.height.value.item(),
+ "z": volume.center[2].value.item()
+ + 0.5 * volume.axis[2] * volume.height.value.item(),
+ }
+
+ else:
+ raise Flow360TranslationError(
+ f"Volume of type {type(volume)} cannot be used with Snappy.",
+ None,
+ ["meshing", "surface_meshing"],
+ )
+
+ translated["geometry"]["refinementVolumes"].append(volume_body)
+
+
+# pylint: disable=too-many-branches,too-many-statements
+def snappy_mesher_json(input_params: SimulationParams):
+ """
+ Get config JSON for snappyHexMesh surface meshing.
"""
translated = {}
- # pylint: disable=duplicate-code
- if input_params.meshing is None:
+ surface_meshing_params = input_params.meshing.surface_meshing
+ # spacing system
+ spacing_system: OctreeSpacing = surface_meshing_params.base_spacing
+
+ # extract geometry information in body: {patch0, ...} format
+ bodies = {}
+ for face_id in input_params.private_attribute_asset_cache.project_entity_info.face_ids:
+ solid = face_id.split("::")
+ if solid[0] not in bodies:
+ bodies[solid[0]] = set()
+ if len(solid) == 2:
+ bodies[solid[0]].add(solid[1])
+
+ # Fill with defaults
+ common_defaults = {
+ "gap": surface_meshing_params.defaults.gap_resolution.value.item(),
+ "spacing": {
+ "min": remove_numerical_noise_from_spacing(
+ surface_meshing_params.defaults.min_spacing, spacing_system
+ ).value.item(),
+ "max": remove_numerical_noise_from_spacing(
+ surface_meshing_params.defaults.max_spacing, spacing_system
+ ).value.item(),
+ },
+ }
+ translated["geometry"] = {
+ "bodies": [
+ {
+ "bodyName": name,
+ **deepcopy(common_defaults),
+ "regions": [{"patchName": region} for region in regions],
+ }
+ for (name, regions) in bodies.items()
+ ]
+ }
+
+ # apply refinements
+ for refinement in (
+ surface_meshing_params.refinements if surface_meshing_params.refinements is not None else []
+ ):
+ if isinstance(refinement, SnappyBodyRefinement):
+ apply_SnappyBodyRefinement(refinement, translated, spacing_system)
+ elif isinstance(refinement, SnappySurfaceEdgeRefinement):
+ apply_SnappySurfaceEdgeRefinement(
+ refinement, translated, surface_meshing_params.defaults, spacing_system
+ )
+ elif isinstance(refinement, SnappyRegionRefinement):
+ apply_SnappyRegionRefinement(refinement, translated, spacing_system)
+ elif isinstance(refinement, UniformRefinement):
+ apply_UniformRefinement_w_snappy(refinement, translated, spacing_system)
+ else:
+ raise Flow360TranslationError(
+ f"Refinement of type {type(refinement)} cannot be used with Snappy.",
+ None,
+ ["meshing", "surface_meshing"],
+ )
+
+ # apply projected volumetric refinements
+ if input_params.meshing.volume_meshing is not None:
+ for refinement in input_params.meshing.volume_meshing.refinements:
+ if isinstance(refinement, UniformRefinement) and refinement.project_to_surface is True:
+ apply_UniformRefinement_w_snappy(refinement, translated, spacing_system)
+
+ # apply settings
+ castellated_mesh_controls = surface_meshing_params.castellated_mesh_controls
+ snap_controls = surface_meshing_params.snap_controls
+ quality_settings = surface_meshing_params.quality_metrics
+ translated["mesherSettings"] = {
+ "snappyHexMesh": {
+ "castellatedMeshControls": {
+ "resolveFeatureAngle": castellated_mesh_controls.resolve_feature_angle.to(
+ "degree"
+ ).value.item(),
+ "nCellsBetweenLevels": castellated_mesh_controls.n_cells_between_levels,
+ "minRefinementCells": castellated_mesh_controls.min_refinement_cells,
+ },
+ "snapControls": {
+ "nSmoothPatch": snap_controls.n_smooth_patch,
+ "tolerance": snap_controls.tolerance,
+ "nSolveIter": snap_controls.n_solve_iter,
+ "nRelaxIter": snap_controls.n_relax_iter,
+ "nFeatureSnapIter": snap_controls.n_feature_snap_iter,
+ "multiRegionFeatureSnap": snap_controls.multi_region_feature_snap,
+ "strictRegionSnap": snap_controls.strict_region_snap,
+ },
+ },
+ "meshQuality": {
+ "maxNonOrtho": (
+ quality_settings.max_non_ortho.to("degree").value.item()
+ if quality_settings.max_non_ortho is not None
+ else 180
+ ),
+ "maxBoundarySkewness": (
+ quality_settings.max_boundary_skewness.to("degree").value.item()
+ if quality_settings.max_boundary_skewness is not None
+ else -1
+ ),
+ "maxInternalSkewness": (
+ quality_settings.max_internal_skewness.to("degree").value.item()
+ if quality_settings.max_internal_skewness is not None
+ else -1
+ ),
+ "maxConcave": (
+ quality_settings.max_concave.to("degree").value.item()
+ if quality_settings.max_concave is not None
+ else 180
+ ),
+ "minVol": (quality_settings.min_vol if quality_settings.min_vol is not None else -1e30),
+ "minTetQuality": (
+ quality_settings.min_tet_quality
+ if quality_settings.min_tet_quality is not None
+ else -1e30
+ ),
+ "minArea": (
+ quality_settings.min_area.value.item()
+ if quality_settings.min_area is not None
+ else -1
+ ),
+ "minTwist": (
+ quality_settings.min_twist if quality_settings.min_twist is not None else -2
+ ),
+ "minDeterminant": (
+ quality_settings.min_determinant
+ if quality_settings.min_determinant is not None
+ else -1e5
+ ),
+ "minVolRatio": (
+ quality_settings.min_vol_ratio if quality_settings.min_vol_ratio is not None else 0
+ ),
+ "minFaceWeight": (
+ quality_settings.min_face_weight
+ if quality_settings.min_face_weight is not None
+ else 0
+ ),
+ "minTriangleTwist": (
+ quality_settings.min_triangle_twist
+ if quality_settings.min_triangle_twist is not None
+ else -1
+ ),
+ "nSmoothScale": (
+ quality_settings.n_smooth_scale
+ if quality_settings.n_smooth_scale is not None
+ else 0
+ ),
+ "errorReduction": (
+ quality_settings.error_reduction
+ if quality_settings.error_reduction is not None
+ else 0
+ ),
+ "minVolCollapseRatio": (
+ quality_settings.min_vol_collapse_ratio
+ if quality_settings.min_vol_collapse_ratio is not None
+ else 0
+ ),
+ },
+ }
+ # smoothing settings
+ smoothing_settings = surface_meshing_params.smooth_controls
+
+ if smoothing_settings is not None:
+ translated["smoothingControls"] = {
+ "lambda": (
+ smoothing_settings.lambda_factor
+ if smoothing_settings.lambda_factor is not None
+ else 0
+ ),
+ "mu": (smoothing_settings.mu_factor if smoothing_settings.mu_factor is not None else 0),
+ "iter": (
+ smoothing_settings.iterations if smoothing_settings.iterations is not None else 0
+ ),
+ }
+ # enforced spacing
+ translated["enforcedSpacing"] = spacing_system.base_spacing.value.item()
+
+ # cad is fluid
+ zones = input_params.meshing.zones
+ for zone in zones:
+ if isinstance(zone, AutomatedFarfield):
+ translated["cadIsFluid"] = False
+ if isinstance(zone, SeedpointZone):
+ translated["cadIsFluid"] = True
+
+ if "cadIsFluid" not in translated:
raise Flow360TranslationError(
- "meshing not specified.",
- None,
- ["meshing"],
+ "Farfield type not specified.", None, ["meshing", "surface_meshing"]
)
+ # points in mesh
+ if zones is not None and translated["cadIsFluid"]:
+ translated["locationInMesh"] = {
+ zone.name: [point.value.item() for point in zone.point_in_mesh]
+ for zone in zones
+ if isinstance(zone, (SeedpointZone, UserDefinedFarfield))
+ }
+
+ return translated
+
+
+def legacy_mesher_json(input_params: SimulationParams):
+ """
+ Get JSON for surface meshing.
+ """
+ translated = {}
+ # pylint: disable=duplicate-code
##:: >> Step 1: Get global maxEdgeLength [REQUIRED]
if input_params.meshing.defaults.surface_max_edge_length is None:
log.info("No `surface_max_edge_length` found in the defaults. Skipping translation.")
@@ -221,8 +631,19 @@ def get_surface_meshing_json(input_params: SimulationParams, mesh_units):
"""
Get JSON for surface meshing.
"""
+ ensure_meshing_is_specified(input_params)
if not input_params.private_attribute_asset_cache.use_geometry_AI:
- return legacy_mesher_json(input_params)
+ if isinstance(input_params.meshing, ModularMeshingWorkflow) and isinstance(
+ input_params.meshing.surface_meshing, SnappySurfaceMeshingParams
+ ):
+ return snappy_mesher_json(input_params)
+ if isinstance(input_params.meshing, MeshingParams):
+ return legacy_mesher_json(input_params)
+ raise Flow360TranslationError(
+ f"translation for {type(input_params.meshing)} not implemented.",
+ None,
+ ["meshing"],
+ )
# === GAI mode ===
input_params.private_attribute_asset_cache.project_entity_info.compute_transformation_matrices()
diff --git a/flow360/component/simulation/translator/utils.py b/flow360/component/simulation/translator/utils.py
index f3d876963..078d92fd7 100644
--- a/flow360/component/simulation/translator/utils.py
+++ b/flow360/component/simulation/translator/utils.py
@@ -22,6 +22,7 @@
from flow360.component.simulation.unit_system import LengthType
from flow360.component.simulation.user_code.core.types import Expression
from flow360.component.simulation.utils import is_exact_instance
+from flow360.exceptions import Flow360TranslationError
def preprocess_input(func):
@@ -440,3 +441,13 @@ def merge_unique_item_lists(list1: list[str], list2: list[str]) -> list:
"""Merge two lists and remove duplicates."""
combined = list1 + list2
return list(OrderedDict.fromkeys(combined))
+
+
+def ensure_meshing_is_specified(input_params: SimulationParams):
+ """Check if meshing parameters are included in SimulationParams."""
+ if input_params.meshing is None:
+ raise Flow360TranslationError(
+ "meshing not specified.",
+ None,
+ ["meshing"],
+ )
diff --git a/flow360/component/simulation/translator/volume_meshing_translator.py b/flow360/component/simulation/translator/volume_meshing_translator.py
index 833595441..abed20eac 100644
--- a/flow360/component/simulation/translator/volume_meshing_translator.py
+++ b/flow360/component/simulation/translator/volume_meshing_translator.py
@@ -1,20 +1,38 @@
"""Volume meshing parameter translator."""
+from typing import Union
+
from flow360.component.simulation.meshing_param.face_params import (
BoundaryLayer,
PassiveSpacing,
)
+from flow360.component.simulation.meshing_param.params import (
+ BetaVolumeMeshingParams,
+ MeshingParams,
+ ModularMeshingWorkflow,
+ SnappySurfaceMeshingParams,
+)
from flow360.component.simulation.meshing_param.volume_params import (
AutomatedFarfield,
AxisymmetricRefinement,
- CylindricalRefinementBase,
+ AxisymmetricRefinementBase,
RotationCylinder,
+ RotationVolume,
+ StructuredBoxRefinement,
UniformRefinement,
UserDefinedFarfield,
)
-from flow360.component.simulation.primitives import Box, CustomVolume, Cylinder, Surface
+from flow360.component.simulation.primitives import (
+ AxisymmetricBody,
+ Box,
+ CustomVolume,
+ Cylinder,
+ SeedpointZone,
+ Surface,
+)
from flow360.component.simulation.simulation_params import SimulationParams
from flow360.component.simulation.translator.utils import (
+ ensure_meshing_is_specified,
get_global_setting_from_first_instance,
preprocess_input,
translate_setting_and_apply_to_all_entities,
@@ -22,6 +40,8 @@
from flow360.component.simulation.utils import is_exact_instance
from flow360.exceptions import Flow360TranslationError
+# pylint: disable=too-many-locals
+
def uniform_refinement_translator(obj: UniformRefinement):
"""
@@ -31,7 +51,7 @@ def uniform_refinement_translator(obj: UniformRefinement):
return {"spacing": obj.spacing.value.item()}
-def cylindrical_refinement_translator(obj: CylindricalRefinementBase):
+def cylindrical_refinement_translator(obj: AxisymmetricRefinementBase):
"""
Translate CylindricalRefinementBase. [SlidingInterface + RotorDisks]
"""
@@ -42,6 +62,17 @@ def cylindrical_refinement_translator(obj: CylindricalRefinementBase):
}
+def box_refinement_translator(obj: StructuredBoxRefinement):
+ """
+ Translate StructuredBoxRefinement spacings
+ """
+ return {
+ "spacingAxis1": obj.spacing_axis1.value.item(),
+ "spacingAxis2": obj.spacing_axis2.value.item(),
+ "spacingNormal": obj.spacing_normal.value.item(),
+ }
+
+
def boundary_layer_translator(obj: BoundaryLayer):
"""
Translate BoundaryLayer.
@@ -74,8 +105,8 @@ def passive_spacing_translator(obj: PassiveSpacing):
}
-def rotation_cylinder_translator(obj: RotationCylinder, rotor_disk_names: list):
- """Setting translation for RotationCylinder."""
+def rotation_volume_translator(obj: RotationVolume, rotor_disk_names: list):
+ """Setting translation for RotationVolume."""
setting = cylindrical_refinement_translator(obj)
setting["enclosedObjects"] = []
if obj.enclosed_entities is not None:
@@ -89,6 +120,10 @@ def rotation_cylinder_translator(obj: RotationCylinder, rotor_disk_names: list):
# Current sliding interface encloses another sliding interface
# Then we append the interace name which is hardcoded "slidingInterface-""
setting["enclosedObjects"].append("slidingInterface-" + entity.name)
+ elif is_exact_instance(entity, AxisymmetricBody):
+ setting["enclosedObjects"].append("slidingInterface-" + entity.name)
+ elif is_exact_instance(entity, Box):
+ setting["enclosedObjects"].append("structuredBox-" + entity.name)
elif is_exact_instance(entity, Surface):
setting["enclosedObjects"].append(entity.name)
return setting
@@ -115,6 +150,25 @@ def refinement_entity_injector(entity_obj):
return {}
+def refinement_entity_box_with_axes_injector(entity_obj: Box):
+ """Injector for Box entity in StructuredBoxRefinement."""
+ lengths = list(entity_obj.size.value)
+
+ axis1 = entity_obj.axes[0]
+ axis2 = entity_obj.axes[1]
+
+ return {
+ "name": entity_obj.name,
+ "type": "box",
+ "lengthAxis1": lengths[0],
+ "lengthAxis2": lengths[1],
+ "lengthNormal": lengths[2],
+ "axis1": list(axis1),
+ "axis2": list(axis2),
+ "center": list(entity_obj.center.value),
+ }
+
+
def rotor_disks_entity_injector(entity: Cylinder):
"""Injector for Cylinder entity in AxisymmetricRefinement."""
@@ -128,16 +182,27 @@ def rotor_disks_entity_injector(entity: Cylinder):
}
-def rotation_cylinder_entity_injector(entity: Cylinder):
+def rotation_volume_entity_injector(entity: Union[Cylinder, AxisymmetricBody]):
"""Injector for Cylinder entity in RotationCylinder."""
- return {
- "name": entity.name,
- "innerRadius": 0 if entity.inner_radius is None else entity.inner_radius.value.item(),
- "outerRadius": entity.outer_radius.value.item(),
- "thickness": entity.height.value.item(),
- "axisOfRotation": list(entity.axis),
- "center": list(entity.center.value),
- }
+ if isinstance(entity, Cylinder):
+ return {
+ "name": entity.name,
+ "type": "Cylinder",
+ "innerRadius": 0 if entity.inner_radius is None else entity.inner_radius.value.item(),
+ "outerRadius": entity.outer_radius.value.item(),
+ "thickness": entity.height.value.item(),
+ "axisOfRotation": list(entity.axis),
+ "center": list(entity.center.value),
+ }
+ if isinstance(entity, AxisymmetricBody):
+ return {
+ "name": entity.name,
+ "type": "Axisymmetric",
+ "profileCurve": [list(profile_point.value) for profile_point in entity.profile_curve],
+ "axisOfRotation": list(entity.axis),
+ "center": list(entity.center.value),
+ }
+ return {}
def _get_custom_volumes(volume_zones: list):
@@ -159,57 +224,96 @@ def _get_custom_volumes(volume_zones: list):
return custom_volumes
+def _get_seedpoint_zones(volume_zones: list):
+ """
+ Get translated seedpoint volumes from volume zones.
+ To be later filled with data from snappyHexMesh.
+ """
+ seedpoint_zones = []
+ for zone in volume_zones:
+ if isinstance(zone, SeedpointZone) or (
+ isinstance(zone, UserDefinedFarfield) and hasattr(zone, "point_in_mesh")
+ ):
+ seedpoint_zones.append(
+ {
+ "name": zone.name,
+ "pointInMesh": [coord.value.item() for coord in zone.point_in_mesh],
+ }
+ )
+ if seedpoint_zones:
+ # Sort custom volumes by name
+ seedpoint_zones.sort(key=lambda x: x["name"])
+ return seedpoint_zones
+
+
@preprocess_input
-# pylint: disable=unused-argument,too-many-branches,too-many-statements
+# pylint: disable=unused-argument,too-many-branches,too-many-statements,too-many-locals
def get_volume_meshing_json(input_params: SimulationParams, mesh_units):
"""
Get JSON for surface meshing.
"""
- translated = {}
+ volume_zones = None
+ refinements = None
+ refinement_factor = None
+ defaults = None
+ gap_treatment_strength = None
- if input_params.meshing is None:
- raise Flow360TranslationError(
- "meshing not specified.",
- None,
- ["meshing"],
- )
+ translated = {}
- if input_params.meshing.volume_zones is None:
+ ensure_meshing_is_specified(input_params)
+
+ if isinstance(input_params.meshing, ModularMeshingWorkflow) and isinstance(
+ input_params.meshing.volume_meshing, BetaVolumeMeshingParams
+ ):
+ volume_zones = input_params.meshing.zones
+ refinements = input_params.meshing.volume_meshing.refinements
+ refinement_factor = input_params.meshing.volume_meshing.refinement_factor
+ defaults = input_params.meshing.volume_meshing.defaults
+ gap_treatment_strength = input_params.meshing.volume_meshing.gap_treatment_strength
+ planar_tolerance = input_params.meshing.volume_meshing.planar_face_tolerance
+
+ if isinstance(input_params.meshing, MeshingParams):
+ volume_zones = input_params.meshing.volume_zones
+ refinements = input_params.meshing.refinements
+ refinement_factor = input_params.meshing.refinement_factor
+ defaults = input_params.meshing.defaults
+ gap_treatment_strength = input_params.meshing.gap_treatment_strength
+ planar_tolerance = input_params.meshing.defaults.planar_face_tolerance
+
+ if volume_zones is None:
raise Flow360TranslationError(
"volume_zones cannot be None for volume meshing",
- input_params.meshing.volume_zones,
+ volume_zones,
["meshing", "volume_zones"],
)
- if input_params.meshing.refinements is None:
+ if refinements is None:
raise Flow360TranslationError(
"No `refinements` found in the input",
- input_params.meshing.refinements,
+ refinements,
["meshing", "refinements"],
)
- meshing_params = input_params.meshing
-
##:: Step 1: Get refinementFactor
- if meshing_params.refinement_factor is None:
+ if refinement_factor is None:
raise Flow360TranslationError(
"No `refinement_factor` found for volume meshing.",
None,
["meshing", "refinement_factor"],
)
- translated["refinementFactor"] = meshing_params.refinement_factor
+ translated["refinementFactor"] = refinement_factor
##:: Step 2: Get farfield
- for zone in input_params.meshing.volume_zones:
- if isinstance(zone, UserDefinedFarfield):
+ for zone in volume_zones:
+ if isinstance(zone, (UserDefinedFarfield, CustomVolume, SeedpointZone)):
translated["farfield"] = {"type": "user-defined"}
break
if isinstance(zone, AutomatedFarfield):
translated["farfield"] = {
"type": zone.method,
- "planarFaceTolerance": meshing_params.defaults.planar_face_tolerance,
+ "planarFaceTolerance": planar_tolerance,
}
break
@@ -223,47 +327,55 @@ def get_volume_meshing_json(input_params: SimulationParams, mesh_units):
##:: Step 3: Get volumetric global settings
translated["volume"] = {}
- if meshing_params.defaults.boundary_layer_first_layer_thickness is None:
+ if defaults.boundary_layer_first_layer_thickness is None:
# `first_layer_thickness` can be locally overridden so after completeness check, we can
# get away with the first instance's value if global one does not exist.
default_first_layer_thickness = get_global_setting_from_first_instance(
- meshing_params.refinements,
+ refinements,
BoundaryLayer,
"first_layer_thickness",
)
else:
- default_first_layer_thickness = meshing_params.defaults.boundary_layer_first_layer_thickness
+ default_first_layer_thickness = defaults.boundary_layer_first_layer_thickness
translated["volume"]["firstLayerThickness"] = default_first_layer_thickness.value.item()
# growthRate can only be global
- translated["volume"]["growthRate"] = meshing_params.defaults.boundary_layer_growth_rate
+ translated["volume"]["growthRate"] = defaults.boundary_layer_growth_rate
- translated["volume"]["gapTreatmentStrength"] = meshing_params.gap_treatment_strength
+ translated["volume"]["gapTreatmentStrength"] = gap_treatment_strength
if input_params.private_attribute_asset_cache.use_inhouse_mesher:
- number_of_boundary_layers = meshing_params.defaults.number_of_boundary_layers
+ number_of_boundary_layers = defaults.number_of_boundary_layers
translated["volume"]["numBoundaryLayers"] = (
number_of_boundary_layers if number_of_boundary_layers is not None else -1
)
- translated["volume"]["planarFaceTolerance"] = meshing_params.defaults.planar_face_tolerance
+ translated["volume"]["planarFaceTolerance"] = planar_tolerance
##:: Step 4: Get volume refinements (uniform + rotorDisks)
uniform_refinement_list = translate_setting_and_apply_to_all_entities(
- meshing_params.refinements,
+ refinements,
UniformRefinement,
uniform_refinement_translator,
to_list=True,
entity_injection_func=refinement_entity_injector,
)
rotor_disk_refinement = translate_setting_and_apply_to_all_entities(
- meshing_params.refinements,
+ refinements,
AxisymmetricRefinement,
cylindrical_refinement_translator,
to_list=True,
entity_injection_func=rotor_disks_entity_injector,
)
+ structured_box_refinement = translate_setting_and_apply_to_all_entities(
+ refinements,
+ StructuredBoxRefinement,
+ box_refinement_translator,
+ to_list=True,
+ entity_injection_func=refinement_entity_box_with_axes_injector,
+ )
+
if uniform_refinement_list:
translated["refinement"] = []
translated["refinement"].extend(uniform_refinement_list)
@@ -274,15 +386,19 @@ def get_volume_meshing_json(input_params: SimulationParams, mesh_units):
translated["rotorDisks"].extend(rotor_disk_refinement)
rotor_disk_names = [item["name"] for item in rotor_disk_refinement]
+ if structured_box_refinement:
+ translated["structuredRegions"] = []
+ translated["structuredRegions"].extend(structured_box_refinement)
+
faces_aniso_setting = translate_setting_and_apply_to_all_entities(
- meshing_params.refinements,
+ refinements,
BoundaryLayer,
boundary_layer_translator,
to_list=False,
)
faces_passive_setting = translate_setting_and_apply_to_all_entities(
- meshing_params.refinements,
+ refinements,
PassiveSpacing,
passive_spacing_translator,
to_list=False,
@@ -294,19 +410,36 @@ def get_volume_meshing_json(input_params: SimulationParams, mesh_units):
##:: Step 5: Get sliding interfaces ()
sliding_interfaces = translate_setting_and_apply_to_all_entities(
- meshing_params.volume_zones,
+ volume_zones,
+ RotationVolume,
+ rotation_volume_translator,
+ to_list=True,
+ entity_injection_func=rotation_volume_entity_injector,
+ translation_func_rotor_disk_names=rotor_disk_names,
+ )
+ sliding_interfaces_cylinders = translate_setting_and_apply_to_all_entities(
+ volume_zones,
RotationCylinder,
- rotation_cylinder_translator,
+ rotation_volume_translator,
to_list=True,
- entity_injection_func=rotation_cylinder_entity_injector,
+ entity_injection_func=rotation_volume_entity_injector,
translation_func_rotor_disk_names=rotor_disk_names,
)
- if sliding_interfaces:
- translated["slidingInterfaces"] = sliding_interfaces
+
+ if sliding_interfaces or sliding_interfaces_cylinders:
+ translated["slidingInterfaces"] = sliding_interfaces + sliding_interfaces_cylinders
##:: Step 6: Get custom volumes
- custom_volumes = _get_custom_volumes(meshing_params.volume_zones)
+ custom_volumes = _get_custom_volumes(volume_zones)
if custom_volumes:
translated["zones"] = custom_volumes
+ ##:: Step 7: Get custom seedpoint zones
+ if isinstance(input_params.meshing, ModularMeshingWorkflow) and isinstance(
+ input_params.meshing.surface_meshing, SnappySurfaceMeshingParams
+ ):
+ seedpoint_zones = _get_seedpoint_zones(volume_zones)
+ if seedpoint_zones:
+ translated["zones"] = seedpoint_zones
+
return translated
diff --git a/flow360/component/simulation/unit_system.py b/flow360/component/simulation/unit_system.py
index c5152053a..02a1dd2dc 100644
--- a/flow360/component/simulation/unit_system.py
+++ b/flow360/component/simulation/unit_system.py
@@ -98,11 +98,11 @@ def resume(self):
unit_system_manager = UnitSystemManager()
-def _encode_ndarray(x):
+def _encode_ndarray(x, enforce_vector=False):
"""
encoder for ndarray
"""
- if x.size == 1:
+ if x.size == 1 and not enforce_vector:
return float(x)
return tuple(x.tolist())
@@ -115,6 +115,14 @@ def _dimensioned_type_serializer(x):
return {"value": _encode_ndarray(x.value), "units": str(x.units.expr)}
+def _dimensioned_vector_type_serializer(x):
+ """
+ encoder for dimensioned type (unyt_quantity, unyt_array, DimensionedType)
+ """
+ # adding .expr helps to avoid degF/C becoming serialized as °F/C
+ return {"value": _encode_ndarray(x.value, True), "units": str(x.units.expr)}
+
+
def _check_if_input_is_nested_collection(value, nest_level):
def get_nesting_level(value):
if isinstance(value, np.ndarray):
@@ -594,7 +602,7 @@ def validate_with_info(value, info):
)
cls_obj.__get_pydantic_json_schema__ = __get_pydantic_json_schema__
- return Annotated[cls_obj, pd.PlainSerializer(_dimensioned_type_serializer)]
+ return Annotated[cls_obj, pd.PlainSerializer(_dimensioned_vector_type_serializer)]
# pylint: disable=too-few-public-methods
class _MatrixType:
@@ -703,6 +711,16 @@ def NonNegativeArray(self):
"""
return self._VectorType.get_class_object(self, length=None, allow_negative_value=False)
+ # pylint: disable=invalid-name
+ @classproperty
+ def PositiveArray(self):
+ """
+ Array value which accepts positive with any length
+ """
+ return self._VectorType.get_class_object(
+ self, length=None, allow_negative_value=False, allow_zero_component=False
+ )
+
# pylint: disable=invalid-name
@classproperty
def Point(self):
@@ -729,6 +747,13 @@ def PositiveVector(self):
self, allow_zero_component=False, allow_negative_value=False
)
+ @classproperty
+ def Pair(self):
+ """
+ Array value which accepts length 2.
+ """
+ return self._VectorType.get_class_object(self, length=2)
+
# pylint: disable=invalid-name
@classproperty
def Direction(self):
diff --git a/flow360/component/simulation/validation/validation_context.py b/flow360/component/simulation/validation/validation_context.py
index 34f79074d..85206023a 100644
--- a/flow360/component/simulation/validation/validation_context.py
+++ b/flow360/component/simulation/validation/validation_context.py
@@ -144,17 +144,22 @@ def _get_farfield_method_(cls, param_as_dict: dict):
volume_zones = None
try:
if param_as_dict["meshing"]:
- volume_zones = param_as_dict["meshing"]["volume_zones"]
+ if param_as_dict["meshing"]["type_name"] == "MeshingParams":
+ volume_zones = param_as_dict["meshing"]["volume_zones"]
+ else:
+ volume_zones = param_as_dict["meshing"]["zones"]
except KeyError:
# No farfield/meshing info.
return None
+
+ farfield_method = None
if volume_zones:
for zone in volume_zones:
if zone["type"] == "AutomatedFarfield":
return zone["method"]
- if zone["type"] == "UserDefinedFarfield":
- return "user-defined"
- return None
+ if zone["type"] in ["UserDefinedFarfield", "CustomVolume", "SeedpointZone"]:
+ farfield_method = "user-defined"
+ return farfield_method
@classmethod
def _get_using_liquid_as_material_(cls, param_as_dict: dict):
@@ -170,10 +175,20 @@ def _get_using_liquid_as_material_(cls, param_as_dict: dict):
@classmethod
def _get_is_beta_mesher_(cls, param_as_dict: dict):
- try:
- return param_as_dict["private_attribute_asset_cache"]["use_inhouse_mesher"]
- except KeyError:
- return False
+ beta_mesher_triggers = []
+ beta_mesher_triggers.append(
+ param_as_dict.get("private_attribute_asset_cache", {}).get("use_inhouse_mesher", False)
+ )
+ if param_as_dict.get("meshing", None) is not None:
+ beta_mesher_triggers.append(
+ param_as_dict.get("meshing", {}).get("surface_meshing", {}).get("type_name", "")
+ == "SnappySurfaceMeshingParams"
+ )
+ beta_mesher_triggers.append(
+ param_as_dict.get("meshing", {}).get("volume_meshing", {}).get("type_name", "")
+ == "BetaVolumeMeshingParams"
+ )
+ return any(beta_mesher_triggers)
@classmethod
def _get_use_geometry_AI_(cls, param_as_dict: dict): # pylint:disable=invalid-name
@@ -225,9 +240,16 @@ def _get_global_bounding_box(cls, param_as_dict: dict):
@classmethod
def _get_planar_face_tolerance(cls, param_as_dict: dict):
- planar_face_tolerance = get_value_with_path(
- param_as_dict, ["meshing", "defaults", "planar_face_tolerance"]
- )
+ planar_face_tolerance = None
+ if "meshing" in param_as_dict and param_as_dict["meshing"]:
+ if param_as_dict["meshing"]["type_name"] == "MeshingParams":
+ planar_face_tolerance = get_value_with_path(
+ param_as_dict, ["meshing", "defaults", "planar_face_tolerance"]
+ )
+ else:
+ planar_face_tolerance = get_value_with_path(
+ param_as_dict, ["meshing", "volume_meshing", "planar_face_tolerance"]
+ )
return planar_face_tolerance
@classmethod
@@ -312,6 +334,8 @@ def _get_at_least_one_body_transformed(cls, param_as_dict: dict): # pylint:disa
@classmethod
def _get_to_be_generated_custom_volumes(cls, param_as_dict: dict):
+ # pylint:disable=fixme
+ # TODO: add seedpoint zones
volume_zones = get_value_with_path(
param_as_dict,
["meshing", "volume_zones"],
diff --git a/flow360/component/simulation/validation/validation_simulation_params.py b/flow360/component/simulation/validation/validation_simulation_params.py
index a470d6bfd..af65b0e00 100644
--- a/flow360/component/simulation/validation/validation_simulation_params.py
+++ b/flow360/component/simulation/validation/validation_simulation_params.py
@@ -4,6 +4,10 @@
from typing import Type, Union, get_args
+from flow360.component.simulation.meshing_param.params import (
+ MeshingParams,
+ ModularMeshingWorkflow,
+)
from flow360.component.simulation.models.solver_numerics import NoneSolver
from flow360.component.simulation.models.surface_models import (
Inflow,
@@ -23,7 +27,7 @@
TimeAverageSurfaceOutput,
VolumeOutput,
)
-from flow360.component.simulation.primitives import CustomVolume
+from flow360.component.simulation.primitives import CustomVolume, SeedpointZone
from flow360.component.simulation.time_stepping.time_stepping import Steady, Unsteady
from flow360.component.simulation.utils import is_exact_instance
from flow360.component.simulation.validation.validation_context import (
@@ -312,7 +316,7 @@ def _validate_cht_has_heat_transfer(params):
def _check_complete_boundary_condition_and_unknown_surface(
params,
-): # pylint:disable=too-many-branches, too-many-locals
+): # pylint:disable=too-many-branches, too-many-locals,too-many-statements
## Step 1: Get all boundaries patches from asset cache
current_lvls = get_validation_levels() if get_validation_levels() else []
if all(level not in current_lvls for level in (ALL, CASE)):
@@ -327,6 +331,11 @@ def _check_complete_boundary_condition_and_unknown_surface(
# Filter out the ones that will be deleted by mesher
automated_farfield_method = params.meshing.automated_farfield_method if params.meshing else None
+ volume_zones = []
+ if isinstance(params.meshing, MeshingParams):
+ volume_zones = params.meshing.volume_zones
+ if isinstance(params.meshing, ModularMeshingWorkflow):
+ volume_zones = params.meshing.zones
if automated_farfield_method:
if validation_info.at_least_one_body_transformed:
@@ -365,7 +374,7 @@ def _check_complete_boundary_condition_and_unknown_surface(
potential_zone_zone_interfaces = set()
if validation_info.farfield_method == "user-defined":
- for zones in params.meshing.volume_zones:
+ for zones in volume_zones:
if isinstance(zones, CustomVolume):
for boundary in zones.boundaries.stored_entities:
potential_zone_zone_interfaces.add(boundary.name)
@@ -402,7 +411,14 @@ def _check_complete_boundary_condition_and_unknown_surface(
missing_boundaries = asset_boundaries - used_boundaries - potential_zone_zone_interfaces
unknown_boundaries = used_boundaries - asset_boundaries
- if missing_boundaries:
+ ## disable missing boundaries with snappy multizone
+ snappy_multizone = False
+ for zone in volume_zones:
+ if isinstance(zone, SeedpointZone):
+ snappy_multizone = True
+ break
+
+ if missing_boundaries and not snappy_multizone:
missing_list = ", ".join(sorted(missing_boundaries))
raise ValueError(
f"The following boundaries do not have a boundary condition: {missing_list}. "
diff --git a/flow360/component/utils.py b/flow360/component/utils.py
index 5a87e3842..fb517953b 100644
--- a/flow360/component/utils.py
+++ b/flow360/component/utils.py
@@ -832,27 +832,41 @@ def _validate_files(cls, value):
MeshFileFormat.STL.ext(),
]
- def _detect_and_validate_mapbc_file(value):
- value_without_mapbc = []
- potential_mapbc_files = []
- mapbc_files = []
- for file in value:
- if match_file_pattern([".mapbc"], file):
- mapbc_files.append(os.path.basename(file))
- continue
- value_without_mapbc.append(file)
- mesh_parser = MeshNameParser(input_mesh_file=file)
+ def _detect_and_validate_mapbc_file(file_paths: list):
+ """Split out .mapbc files, warn for orphans, and return non-.mapbc files.
+
+ The returned list excludes any `.mapbc` files so downstream validators only see
+ geometry/surface-mesh inputs. We also warn when a provided `.mapbc` file does not
+ correspond to any detected UGRID mesh file in the same input list.
+ """
+
+ # Separate mapbc and non-mapbc files first for clarity
+ mapbc_file_paths = [
+ file_path for file_path in file_paths if match_file_pattern([".mapbc"], file_path)
+ ]
+ non_mapbc_file_paths = [
+ file_path
+ for file_path in file_paths
+ if not match_file_pattern([".mapbc"], file_path)
+ ]
+
+ # Build the set of expected .mapbc paths based on detected UGRID mesh files
+ expected_mapbc_file_paths = set()
+ for file_path in non_mapbc_file_paths:
+ mesh_parser = MeshNameParser(input_mesh_file=file_path)
if mesh_parser.is_ugrid():
- potential_mapbc_files.append(get_mapbc_from_ugrid(file))
+ expected_mapbc_file_paths.add(get_mapbc_from_ugrid(file_path))
- for mapbc_file in mapbc_files:
- if mapbc_file not in potential_mapbc_files:
+ # Warn for any provided .mapbc that does not match an expected path
+ for mapbc_file_path in mapbc_file_paths:
+ if mapbc_file_path not in expected_mapbc_file_paths:
log.warning(
- f"Cannot find the ugrid file associated with the given mapbc file: '{mapbc_file}' so "
- f"this mapbc file will be ignored."
+ "Cannot find the ugrid file associated with the "
+ f"given mapbc file: '{mapbc_file_path}' in the input list."
)
- return value_without_mapbc
+ # Only return non-.mapbc files for further validation
+ return non_mapbc_file_paths
def _validate_single_file(value=None):
"""Validate a single file and both geometry and surface mesh files are accepted"""
diff --git a/flow360/component/v1/updater.py b/flow360/component/v1/updater.py
index 574348740..47ecc2414 100644
--- a/flow360/component/v1/updater.py
+++ b/flow360/component/v1/updater.py
@@ -30,6 +30,7 @@ def _no_update(params_as_dict):
("25.4.1", "25.5.*", _no_update),
("25.5.*", "25.6.*", _no_update),
("25.6.*", "25.7.*", _no_update),
+ ("25.7.*", "25.8.*", _no_update),
]
diff --git a/flow360/examples/__init__.py b/flow360/examples/__init__.py
index 3083603b8..defb21fc0 100644
--- a/flow360/examples/__init__.py
+++ b/flow360/examples/__init__.py
@@ -4,6 +4,7 @@
from .bet_example_data import BETExampleData
from .bet_line import BETLine
from .convergence import Convergence
+from .cube import Cube
from .cylinder2D import Cylinder2D
from .cylinder3D import Cylinder3D
from .drivaer import DrivAer
@@ -31,6 +32,7 @@
"BETExampleData",
"BETLine",
"Convergence",
+ "Cube",
"Cylinder2D",
"Cylinder3D",
"DrivAer",
diff --git a/flow360/examples/cube.py b/flow360/examples/cube.py
new file mode 100644
index 000000000..00831768e
--- /dev/null
+++ b/flow360/examples/cube.py
@@ -0,0 +1,12 @@
+"""
+cube geometry example
+"""
+
+from .base_test_case import BaseTestCase
+
+
+class Cube(BaseTestCase):
+ name = "cube"
+
+ class url:
+ geometry = "https://simcloud-public-1.s3.amazonaws.com/cube/cube.stl"
diff --git a/flow360/version.py b/flow360/version.py
index 819dd52d0..75fbc7a44 100644
--- a/flow360/version.py
+++ b/flow360/version.py
@@ -2,5 +2,5 @@
version
"""
-__version__ = "25.7.4b0"
+__version__ = "25.8.0b3"
__solver_version__ = "release-25.7"
diff --git a/poetry.lock b/poetry.lock
index b34e4d76d..1e4a20f8d 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 2.2.0 and should not be changed by hand.
+# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand.
[[package]]
name = "accessible-pygments"
@@ -27,12 +27,25 @@ description = "A light, configurable Sphinx theme"
optional = false
python-versions = ">=3.9"
groups = ["main"]
-markers = "extra == \"docs\""
+markers = "python_version == \"3.9\" and extra == \"docs\""
files = [
{file = "alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92"},
{file = "alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65"},
]
+[[package]]
+name = "alabaster"
+version = "1.0.0"
+description = "A light, configurable Sphinx theme"
+optional = false
+python-versions = ">=3.10"
+groups = ["main"]
+markers = "extra == \"docs\" and python_version >= \"3.10\""
+files = [
+ {file = "alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b"},
+ {file = "alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e"},
+]
+
[[package]]
name = "annotated-types"
version = "0.7.0"
@@ -674,6 +687,7 @@ files = [
{file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"},
{file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"},
]
+markers = {main = "platform_python_implementation == \"PyPy\" or extra == \"docs\" or implementation_name == \"pypy\"", dev = "implementation_name == \"pypy\""}
[package.dependencies]
pycparser = "*"
@@ -787,6 +801,7 @@ description = "Composable command line interface toolkit"
optional = false
python-versions = ">=3.7"
groups = ["main", "dev"]
+markers = "python_version == \"3.9\""
files = [
{file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"},
{file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"},
@@ -795,6 +810,22 @@ files = [
[package.dependencies]
colorama = {version = "*", markers = "platform_system == \"Windows\""}
+[[package]]
+name = "click"
+version = "8.2.1"
+description = "Composable command line interface toolkit"
+optional = false
+python-versions = ">=3.10"
+groups = ["main", "dev"]
+markers = "python_version >= \"3.10\""
+files = [
+ {file = "click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b"},
+ {file = "click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202"},
+]
+
+[package.dependencies]
+colorama = {version = "*", markers = "platform_system == \"Windows\""}
+
[[package]]
name = "cmd2"
version = "2.7.0"
@@ -825,7 +856,7 @@ files = [
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
]
-markers = {dev = "platform_system == \"Windows\" or sys_platform == \"win32\""}
+markers = {dev = "sys_platform == \"win32\" or platform_system == \"Windows\""}
[[package]]
name = "colorful"
@@ -1916,6 +1947,7 @@ description = "IPython: Productive Interactive Computing"
optional = false
python-versions = ">=3.9"
groups = ["main", "dev"]
+markers = "python_version == \"3.9\""
files = [
{file = "ipython-8.18.1-py3-none-any.whl", hash = "sha256:e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397"},
{file = "ipython-8.18.1.tar.gz", hash = "sha256:ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27"},
@@ -1947,6 +1979,96 @@ qtconsole = ["qtconsole"]
test = ["pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath"]
test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath", "trio"]
+[[package]]
+name = "ipython"
+version = "8.37.0"
+description = "IPython: Productive Interactive Computing"
+optional = false
+python-versions = ">=3.10"
+groups = ["main", "dev"]
+markers = "python_version == \"3.10\""
+files = [
+ {file = "ipython-8.37.0-py3-none-any.whl", hash = "sha256:ed87326596b878932dbcb171e3e698845434d8c61b8d8cd474bf663041a9dcf2"},
+ {file = "ipython-8.37.0.tar.gz", hash = "sha256:ca815841e1a41a1e6b73a0b08f3038af9b2252564d01fc405356d34033012216"},
+]
+
+[package.dependencies]
+colorama = {version = "*", markers = "sys_platform == \"win32\""}
+decorator = "*"
+exceptiongroup = {version = "*", markers = "python_version < \"3.11\""}
+jedi = ">=0.16"
+matplotlib-inline = "*"
+pexpect = {version = ">4.3", markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""}
+prompt_toolkit = ">=3.0.41,<3.1.0"
+pygments = ">=2.4.0"
+stack_data = "*"
+traitlets = ">=5.13.0"
+typing_extensions = {version = ">=4.6", markers = "python_version < \"3.12\""}
+
+[package.extras]
+all = ["ipython[black,doc,kernel,matplotlib,nbconvert,nbformat,notebook,parallel,qtconsole]", "ipython[test,test-extra]"]
+black = ["black"]
+doc = ["docrepr", "exceptiongroup", "intersphinx_registry", "ipykernel", "ipython[test]", "matplotlib", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "sphinxcontrib-jquery", "tomli ; python_version < \"3.11\"", "typing_extensions"]
+kernel = ["ipykernel"]
+matplotlib = ["matplotlib"]
+nbconvert = ["nbconvert"]
+nbformat = ["nbformat"]
+notebook = ["ipywidgets", "notebook"]
+parallel = ["ipyparallel"]
+qtconsole = ["qtconsole"]
+test = ["packaging", "pickleshare", "pytest", "pytest-asyncio (<0.22)", "testpath"]
+test-extra = ["curio", "ipython[test]", "jupyter_ai", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.23)", "pandas", "trio"]
+
+[[package]]
+name = "ipython"
+version = "9.4.0"
+description = "IPython: Productive Interactive Computing"
+optional = false
+python-versions = ">=3.11"
+groups = ["main", "dev"]
+markers = "python_version >= \"3.11\""
+files = [
+ {file = "ipython-9.4.0-py3-none-any.whl", hash = "sha256:25850f025a446d9b359e8d296ba175a36aedd32e83ca9b5060430fe16801f066"},
+ {file = "ipython-9.4.0.tar.gz", hash = "sha256:c033c6d4e7914c3d9768aabe76bbe87ba1dc66a92a05db6bfa1125d81f2ee270"},
+]
+
+[package.dependencies]
+colorama = {version = "*", markers = "sys_platform == \"win32\""}
+decorator = "*"
+ipython-pygments-lexers = "*"
+jedi = ">=0.16"
+matplotlib-inline = "*"
+pexpect = {version = ">4.3", markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""}
+prompt_toolkit = ">=3.0.41,<3.1.0"
+pygments = ">=2.4.0"
+stack_data = "*"
+traitlets = ">=5.13.0"
+typing_extensions = {version = ">=4.6", markers = "python_version < \"3.12\""}
+
+[package.extras]
+all = ["ipython[doc,matplotlib,test,test-extra]"]
+black = ["black"]
+doc = ["docrepr", "exceptiongroup", "intersphinx_registry", "ipykernel", "ipython[test]", "matplotlib", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "sphinx_toml (==0.0.4)", "typing_extensions"]
+matplotlib = ["matplotlib"]
+test = ["packaging", "pytest", "pytest-asyncio (<0.22)", "testpath"]
+test-extra = ["curio", "ipykernel", "ipython[test]", "jupyter_ai", "matplotlib (!=3.2.0)", "nbclient", "nbformat", "numpy (>=1.23)", "pandas", "trio"]
+
+[[package]]
+name = "ipython-pygments-lexers"
+version = "1.1.1"
+description = "Defines a variety of Pygments lexers for highlighting IPython code."
+optional = false
+python-versions = ">=3.8"
+groups = ["main", "dev"]
+markers = "python_version >= \"3.11\""
+files = [
+ {file = "ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c"},
+ {file = "ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81"},
+]
+
+[package.dependencies]
+pygments = "*"
+
[[package]]
name = "ipywidgets"
version = "8.1.7"
@@ -3183,7 +3305,7 @@ description = "An extended [CommonMark](https://spec.commonmark.org/) compliant
optional = true
python-versions = ">=3.8"
groups = ["main"]
-markers = "extra == \"docs\""
+markers = "python_version == \"3.9\" and extra == \"docs\""
files = [
{file = "myst_parser-3.0.1-py3-none-any.whl", hash = "sha256:6457aaa33a5d474aca678b8ead9b3dc298e89c68e67012e73146ea6fd54babf1"},
{file = "myst_parser-3.0.1.tar.gz", hash = "sha256:88f0cb406cb363b077d176b51c476f62d60604d68a8dcdf4832e080441301a87"},
@@ -3204,6 +3326,34 @@ rtd = ["ipython", "sphinx (>=7)", "sphinx-autodoc2 (>=0.5.0,<0.6.0)", "sphinx-bo
testing = ["beautifulsoup4", "coverage[toml]", "defusedxml", "pytest (>=8,<9)", "pytest-cov", "pytest-param-files (>=0.6.0,<0.7.0)", "pytest-regressions", "sphinx-pytest"]
testing-docutils = ["pygments", "pytest (>=8,<9)", "pytest-param-files (>=0.6.0,<0.7.0)"]
+[[package]]
+name = "myst-parser"
+version = "4.0.1"
+description = "An extended [CommonMark](https://spec.commonmark.org/) compliant parser,"
+optional = true
+python-versions = ">=3.10"
+groups = ["main"]
+markers = "extra == \"docs\" and python_version >= \"3.10\""
+files = [
+ {file = "myst_parser-4.0.1-py3-none-any.whl", hash = "sha256:9134e88959ec3b5780aedf8a99680ea242869d012e8821db3126d427edc9c95d"},
+ {file = "myst_parser-4.0.1.tar.gz", hash = "sha256:5cfea715e4f3574138aecbf7d54132296bfd72bb614d31168f48c477a830a7c4"},
+]
+
+[package.dependencies]
+docutils = ">=0.19,<0.22"
+jinja2 = "*"
+markdown-it-py = ">=3.0,<4.0"
+mdit-py-plugins = ">=0.4.1,<1.0"
+pyyaml = "*"
+sphinx = ">=7,<9"
+
+[package.extras]
+code-style = ["pre-commit (>=4.0,<5.0)"]
+linkify = ["linkify-it-py (>=2.0,<3.0)"]
+rtd = ["ipython", "sphinx (>=7)", "sphinx-autodoc2 (>=0.5.0,<0.6.0)", "sphinx-book-theme (>=1.1,<2.0)", "sphinx-copybutton", "sphinx-design", "sphinx-pyscript", "sphinx-tippy (>=0.4.3)", "sphinx-togglebutton", "sphinxext-opengraph (>=0.9.0,<0.10.0)", "sphinxext-rediraffe (>=0.2.7,<0.3.0)"]
+testing = ["beautifulsoup4", "coverage[toml]", "defusedxml", "pygments (<2.19)", "pytest (>=8,<9)", "pytest-cov", "pytest-param-files (>=0.6.0,<0.7.0)", "pytest-regressions", "sphinx-pytest"]
+testing-docutils = ["pygments", "pytest (>=8,<9)", "pytest-param-files (>=0.6.0,<0.7.0)"]
+
[[package]]
name = "natsort"
version = "8.4.0"
@@ -3339,7 +3489,7 @@ description = "Jupyter Notebook Tools for Sphinx"
optional = true
python-versions = ">=3.6"
groups = ["main"]
-markers = "extra == \"docs\""
+markers = "python_version >= \"3.11\" and extra == \"docs\""
files = [
{file = "nbsphinx-0.9.7-py3-none-any.whl", hash = "sha256:7292c3767fea29e405c60743eee5393682a83982ab202ff98f5eb2db02629da8"},
{file = "nbsphinx-0.9.7.tar.gz", hash = "sha256:abd298a686d55fa894ef697c51d44f24e53aa312dadae38e82920f250a5456fe"},
@@ -3414,6 +3564,7 @@ description = "Fast numerical expression evaluator for NumPy"
optional = false
python-versions = ">=3.9"
groups = ["main"]
+markers = "python_version == \"3.9\""
files = [
{file = "numexpr-2.10.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b5b0e82d2109c1d9e63fcd5ea177d80a11b881157ab61178ddbdebd4c561ea46"},
{file = "numexpr-2.10.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3fc2b8035a0c2cdc352e58c3875cb668836018065cbf5752cb531015d9a568d8"},
@@ -3456,6 +3607,51 @@ files = [
[package.dependencies]
numpy = ">=1.23.0"
+[[package]]
+name = "numexpr"
+version = "2.11.0"
+description = "Fast numerical expression evaluator for NumPy"
+optional = false
+python-versions = ">=3.10"
+groups = ["main"]
+markers = "python_version >= \"3.10\""
+files = [
+ {file = "numexpr-2.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7f471fd055a9e13cf5f4337ee12379b30b4dcda1ae0d85018d4649e841578c02"},
+ {file = "numexpr-2.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6e68a9800a3fa37c438b73a669f507c4973801a456a864ac56b62c3bd63d08af"},
+ {file = "numexpr-2.11.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ad5cf0ebc3cdb12edb5aa50472108807ffd0a0ce95f87c0366a479fa83a7c346"},
+ {file = "numexpr-2.11.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8c9e6b07c136d06495c792f603099039bb1e7c6c29854cc5eb3d7640268df016"},
+ {file = "numexpr-2.11.0-cp310-cp310-win32.whl", hash = "sha256:4aba2f640d9d45b986a613ce94fcf008c42cc72eeba2990fefdb575228b1d3d1"},
+ {file = "numexpr-2.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:7f75797bc75a2e7edf52a1c9e68a1295fa84250161c8f4e41df9e72723332c65"},
+ {file = "numexpr-2.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:450eba3c93c3e3e8070566ad8d70590949d6e574b1c960bf68edd789811e7da8"},
+ {file = "numexpr-2.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f0eb88dbac8a7e61ee433006d0ddfd6eb921f5c6c224d1b50855bc98fb304c44"},
+ {file = "numexpr-2.11.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a194e3684b3553ea199c3f4837f422a521c7e2f0cce13527adc3a6b4049f9e7c"},
+ {file = "numexpr-2.11.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f677668ab2bb2452fee955af3702fbb3b71919e61e4520762b1e5f54af59c0d8"},
+ {file = "numexpr-2.11.0-cp311-cp311-win32.whl", hash = "sha256:7d9e76a77c9644fbd60da3984e516ead5b84817748c2da92515cd36f1941a04d"},
+ {file = "numexpr-2.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:7163b488bfdcd13c300a8407c309e4cee195ef95d07facf5ac2678d66c988805"},
+ {file = "numexpr-2.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4229060be866813122385c608bbd3ea48fe0b33e91f2756810d28c1cdbfc98f1"},
+ {file = "numexpr-2.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:097aa8835d32d6ac52f2be543384019b4b134d1fb67998cbfc4271155edfe54a"},
+ {file = "numexpr-2.11.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f082321c244ff5d0e252071fb2c4fe02063a45934144a1456a5370ca139bec2"},
+ {file = "numexpr-2.11.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7a19435ca3d7dd502b8d8dce643555eb1b6013989e3f7577857289f6db6be16"},
+ {file = "numexpr-2.11.0-cp312-cp312-win32.whl", hash = "sha256:f326218262c8d8537887cc4bbd613c8409d62f2cac799835c0360e0d9cefaa5c"},
+ {file = "numexpr-2.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:0a184e5930c77ab91dd9beee4df403b825cd9dfc4e9ba4670d31c9fcb4e2c08e"},
+ {file = "numexpr-2.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:eb766218abad05c7c3ddad5367d0ec702d6152cb4a48d9fd56a6cef6abade70c"},
+ {file = "numexpr-2.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2036be213a6a1b5ce49acf60de99b911a0f9d174aab7679dde1fae315134f826"},
+ {file = "numexpr-2.11.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:096ec768bee2ef14ac757b4178e3c5f05e5f1cb6cae83b2eea9b4ba3ec1a86dd"},
+ {file = "numexpr-2.11.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a1719788a787808c15c9bb98b6ff0c97d64a0e59c1a6ebe36d4ae4d7c5c09b95"},
+ {file = "numexpr-2.11.0-cp313-cp313-win32.whl", hash = "sha256:6b5fdfc86cbf5373ea67d554cc6f08863825ea8e928416bed8d5285e387420c6"},
+ {file = "numexpr-2.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:5ff337b36db141a1a0b49f01282783744f49f0d401cc83a512fc5596eb7db5c6"},
+ {file = "numexpr-2.11.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:b9854fa70edbe93242b8bb4840e58d1128c45766d9a70710f05b4f67eb0feb6e"},
+ {file = "numexpr-2.11.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:321736cb98f090ce864b58cc5c37661cb5548e394e0fe24d5f2c7892a89070c3"},
+ {file = "numexpr-2.11.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5cc434eb4a4df2fe442bcc50df114e82ff7aa234657baf873b2c9cf3f851e8e"},
+ {file = "numexpr-2.11.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:238d19465a272ada3967600fada55e4c6900485aefb42122a78dfcaf2efca65f"},
+ {file = "numexpr-2.11.0-cp313-cp313t-win32.whl", hash = "sha256:0db4c2dcad09f9594b45fce794f4b903345195a8c216e252de2aa92884fd81a8"},
+ {file = "numexpr-2.11.0-cp313-cp313t-win_amd64.whl", hash = "sha256:a69b5c02014448a412012752dc46091902d28932c3be0c6e02e73cecceffb700"},
+ {file = "numexpr-2.11.0.tar.gz", hash = "sha256:75b2c01a4eda2e7c357bc67a3f5c3dd76506c15b5fd4dc42845ef2e182181bad"},
+]
+
+[package.dependencies]
+numpy = ">=1.23.0"
+
[[package]]
name = "numpy"
version = "2.0.2"
@@ -3853,7 +4049,7 @@ description = "Pexpect allows easy control of interactive console applications."
optional = false
python-versions = "*"
groups = ["main", "dev"]
-markers = "sys_platform != \"win32\""
+markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\" or python_version == \"3.9\" and sys_platform != \"win32\""
files = [
{file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"},
{file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"},
@@ -4120,7 +4316,7 @@ description = "Run a subprocess in a pseudo terminal"
optional = false
python-versions = "*"
groups = ["main", "dev"]
-markers = "sys_platform != \"win32\" or os_name != \"nt\""
+markers = "(sys_platform != \"win32\" or os_name != \"nt\") and (sys_platform != \"win32\" and sys_platform != \"emscripten\" or os_name != \"nt\" or python_version == \"3.9\")"
files = [
{file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"},
{file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"},
@@ -4152,6 +4348,7 @@ files = [
{file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"},
{file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"},
]
+markers = {main = "platform_python_implementation == \"PyPy\" or extra == \"docs\" or implementation_name == \"pypy\"", dev = "implementation_name == \"pypy\""}
[[package]]
name = "pydantic"
@@ -5118,7 +5315,6 @@ files = [
{file = "ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f66efbc1caa63c088dead1c4170d148eabc9b80d95fb75b6c92ac0aad2437d76"},
{file = "ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:22353049ba4181685023b25b5b51a574bce33e7f51c759371a7422dcae5402a6"},
{file = "ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:932205970b9f9991b34f55136be327501903f7c66830e9760a8ffb15b07f05cd"},
- {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a52d48f4e7bf9005e8f0a89209bf9a73f7190ddf0489eee5eb51377385f59f2a"},
{file = "ruamel.yaml.clib-0.2.12-cp310-cp310-win32.whl", hash = "sha256:3eac5a91891ceb88138c113f9db04f3cebdae277f5d44eaa3651a4f573e6a5da"},
{file = "ruamel.yaml.clib-0.2.12-cp310-cp310-win_amd64.whl", hash = "sha256:ab007f2f5a87bd08ab1499bdf96f3d5c6ad4dcfa364884cb4549aa0154b13a28"},
{file = "ruamel.yaml.clib-0.2.12-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:4a6679521a58256a90b0d89e03992c15144c5f3858f40d7c18886023d7943db6"},
@@ -5127,7 +5323,6 @@ files = [
{file = "ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:811ea1594b8a0fb466172c384267a4e5e367298af6b228931f273b111f17ef52"},
{file = "ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cf12567a7b565cbf65d438dec6cfbe2917d3c1bdddfce84a9930b7d35ea59642"},
{file = "ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7dd5adc8b930b12c8fc5b99e2d535a09889941aa0d0bd06f4749e9a9397c71d2"},
- {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1492a6051dab8d912fc2adeef0e8c72216b24d57bd896ea607cb90bb0c4981d3"},
{file = "ruamel.yaml.clib-0.2.12-cp311-cp311-win32.whl", hash = "sha256:bd0a08f0bab19093c54e18a14a10b4322e1eacc5217056f3c063bd2f59853ce4"},
{file = "ruamel.yaml.clib-0.2.12-cp311-cp311-win_amd64.whl", hash = "sha256:a274fb2cb086c7a3dea4322ec27f4cb5cc4b6298adb583ab0e211a4682f241eb"},
{file = "ruamel.yaml.clib-0.2.12-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:20b0f8dc160ba83b6dcc0e256846e1a02d044e13f7ea74a3d1d56ede4e48c632"},
@@ -5136,7 +5331,6 @@ files = [
{file = "ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:749c16fcc4a2b09f28843cda5a193e0283e47454b63ec4b81eaa2242f50e4ccd"},
{file = "ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bf165fef1f223beae7333275156ab2022cffe255dcc51c27f066b4370da81e31"},
{file = "ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:32621c177bbf782ca5a18ba4d7af0f1082a3f6e517ac2a18b3974d4edf349680"},
- {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b82a7c94a498853aa0b272fd5bc67f29008da798d4f93a2f9f289feb8426a58d"},
{file = "ruamel.yaml.clib-0.2.12-cp312-cp312-win32.whl", hash = "sha256:e8c4ebfcfd57177b572e2040777b8abc537cdef58a2120e830124946aa9b42c5"},
{file = "ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl", hash = "sha256:0467c5965282c62203273b838ae77c0d29d7638c8a4e3a1c8bdd3602c10904e4"},
{file = "ruamel.yaml.clib-0.2.12-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4c8c5d82f50bb53986a5e02d1b3092b03622c02c2eb78e29bec33fd9593bae1a"},
@@ -5145,7 +5339,6 @@ files = [
{file = "ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96777d473c05ee3e5e3c3e999f5d23c6f4ec5b0c38c098b3a5229085f74236c6"},
{file = "ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:3bc2a80e6420ca8b7d3590791e2dfc709c88ab9152c00eeb511c9875ce5778bf"},
{file = "ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e188d2699864c11c36cdfdada94d781fd5d6b0071cd9c427bceb08ad3d7c70e1"},
- {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f6f3eac23941b32afccc23081e1f50612bdbe4e982012ef4f5797986828cd01"},
{file = "ruamel.yaml.clib-0.2.12-cp313-cp313-win32.whl", hash = "sha256:6442cb36270b3afb1b4951f060eccca1ce49f3d087ca1ca4563a6eb479cb3de6"},
{file = "ruamel.yaml.clib-0.2.12-cp313-cp313-win_amd64.whl", hash = "sha256:e5b8daf27af0b90da7bb903a876477a9e6d7270be6146906b276605997c7e9a3"},
{file = "ruamel.yaml.clib-0.2.12-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:fc4b630cd3fa2cf7fce38afa91d7cfe844a9f75d7f0f36393fa98815e911d987"},
@@ -5154,7 +5347,6 @@ files = [
{file = "ruamel.yaml.clib-0.2.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2f1c3765db32be59d18ab3953f43ab62a761327aafc1594a2a1fbe038b8b8a7"},
{file = "ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:d85252669dc32f98ebcd5d36768f5d4faeaeaa2d655ac0473be490ecdae3c285"},
{file = "ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e143ada795c341b56de9418c58d028989093ee611aa27ffb9b7f609c00d813ed"},
- {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2c59aa6170b990d8d2719323e628aaf36f3bfbc1c26279c0eeeb24d05d2d11c7"},
{file = "ruamel.yaml.clib-0.2.12-cp39-cp39-win32.whl", hash = "sha256:beffaed67936fbbeffd10966a4eb53c402fafd3d6833770516bf7314bc6ffa12"},
{file = "ruamel.yaml.clib-0.2.12-cp39-cp39-win_amd64.whl", hash = "sha256:040ae85536960525ea62868b642bdb0c2cc6021c9f9d507810c0c604e66f5a7b"},
{file = "ruamel.yaml.clib-0.2.12.tar.gz", hash = "sha256:6c8fbb13ec503f99a91901ab46e0b07ae7941cd527393187039aec586fdfd36f"},
@@ -5495,7 +5687,7 @@ description = "Python documentation generator"
optional = false
python-versions = ">=3.9"
groups = ["main"]
-markers = "extra == \"docs\""
+markers = "python_version == \"3.9\" and extra == \"docs\""
files = [
{file = "sphinx-7.4.7-py3-none-any.whl", hash = "sha256:c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239"},
{file = "sphinx-7.4.7.tar.gz", hash = "sha256:242f92a7ea7e6c5b406fdc2615413890ba9f699114a9c09192d7dfead2ee9cfe"},
@@ -5526,6 +5718,80 @@ docs = ["sphinxcontrib-websupport"]
lint = ["flake8 (>=6.0)", "importlib-metadata (>=6.0)", "mypy (==1.10.1)", "pytest (>=6.0)", "ruff (==0.5.2)", "sphinx-lint (>=0.9)", "tomli (>=2)", "types-docutils (==0.21.0.20240711)", "types-requests (>=2.30.0)"]
test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "setuptools (>=70.0)", "typing_extensions (>=4.9)"]
+[[package]]
+name = "sphinx"
+version = "8.1.3"
+description = "Python documentation generator"
+optional = false
+python-versions = ">=3.10"
+groups = ["main"]
+markers = "python_version == \"3.10\" and extra == \"docs\""
+files = [
+ {file = "sphinx-8.1.3-py3-none-any.whl", hash = "sha256:09719015511837b76bf6e03e42eb7595ac8c2e41eeb9c29c5b755c6b677992a2"},
+ {file = "sphinx-8.1.3.tar.gz", hash = "sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927"},
+]
+
+[package.dependencies]
+alabaster = ">=0.7.14"
+babel = ">=2.13"
+colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""}
+docutils = ">=0.20,<0.22"
+imagesize = ">=1.3"
+Jinja2 = ">=3.1"
+packaging = ">=23.0"
+Pygments = ">=2.17"
+requests = ">=2.30.0"
+snowballstemmer = ">=2.2"
+sphinxcontrib-applehelp = ">=1.0.7"
+sphinxcontrib-devhelp = ">=1.0.6"
+sphinxcontrib-htmlhelp = ">=2.0.6"
+sphinxcontrib-jsmath = ">=1.0.1"
+sphinxcontrib-qthelp = ">=1.0.6"
+sphinxcontrib-serializinghtml = ">=1.1.9"
+tomli = {version = ">=2", markers = "python_version < \"3.11\""}
+
+[package.extras]
+docs = ["sphinxcontrib-websupport"]
+lint = ["flake8 (>=6.0)", "mypy (==1.11.1)", "pyright (==1.1.384)", "pytest (>=6.0)", "ruff (==0.6.9)", "sphinx-lint (>=0.9)", "tomli (>=2)", "types-Pillow (==10.2.0.20240822)", "types-Pygments (==2.18.0.20240506)", "types-colorama (==0.4.15.20240311)", "types-defusedxml (==0.7.0.20240218)", "types-docutils (==0.21.0.20241005)", "types-requests (==2.32.0.20240914)", "types-urllib3 (==1.26.25.14)"]
+test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "setuptools (>=70.0)", "typing_extensions (>=4.9)"]
+
+[[package]]
+name = "sphinx"
+version = "8.2.3"
+description = "Python documentation generator"
+optional = false
+python-versions = ">=3.11"
+groups = ["main"]
+markers = "python_version >= \"3.11\" and extra == \"docs\""
+files = [
+ {file = "sphinx-8.2.3-py3-none-any.whl", hash = "sha256:4405915165f13521d875a8c29c8970800a0141c14cc5416a38feca4ea5d9b9c3"},
+ {file = "sphinx-8.2.3.tar.gz", hash = "sha256:398ad29dee7f63a75888314e9424d40f52ce5a6a87ae88e7071e80af296ec348"},
+]
+
+[package.dependencies]
+alabaster = ">=0.7.14"
+babel = ">=2.13"
+colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""}
+docutils = ">=0.20,<0.22"
+imagesize = ">=1.3"
+Jinja2 = ">=3.1"
+packaging = ">=23.0"
+Pygments = ">=2.17"
+requests = ">=2.30.0"
+roman-numerals-py = ">=1.0.0"
+snowballstemmer = ">=2.2"
+sphinxcontrib-applehelp = ">=1.0.7"
+sphinxcontrib-devhelp = ">=1.0.6"
+sphinxcontrib-htmlhelp = ">=2.0.6"
+sphinxcontrib-jsmath = ">=1.0.1"
+sphinxcontrib-qthelp = ">=1.0.6"
+sphinxcontrib-serializinghtml = ">=1.1.9"
+
+[package.extras]
+docs = ["sphinxcontrib-websupport"]
+lint = ["betterproto (==2.0.0b6)", "mypy (==1.15.0)", "pypi-attestations (==0.0.21)", "pyright (==1.1.395)", "pytest (>=8.0)", "ruff (==0.9.9)", "sphinx-lint (>=0.9)", "types-Pillow (==10.2.0.20240822)", "types-Pygments (==2.19.0.20250219)", "types-colorama (==0.4.15.20240311)", "types-defusedxml (==0.7.0.20240218)", "types-docutils (==0.21.0.20241128)", "types-requests (==2.32.0.20241016)", "types-urllib3 (==1.26.25.14)"]
+test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "pytest-xdist[psutil] (>=3.4)", "setuptools (>=70.0)", "typing_extensions (>=4.9)"]
+
[[package]]
name = "sphinx-autodoc-typehints"
version = "2.3.0"
@@ -5533,7 +5799,7 @@ description = "Type hints (PEP 484) support for the Sphinx autodoc extension"
optional = true
python-versions = ">=3.9"
groups = ["main"]
-markers = "extra == \"docs\""
+markers = "python_version == \"3.9\" and extra == \"docs\""
files = [
{file = "sphinx_autodoc_typehints-2.3.0-py3-none-any.whl", hash = "sha256:3098e2c6d0ba99eacd013eb06861acc9b51c6e595be86ab05c08ee5506ac0c67"},
{file = "sphinx_autodoc_typehints-2.3.0.tar.gz", hash = "sha256:535c78ed2d6a1bad393ba9f3dfa2602cf424e2631ee207263e07874c38fde084"},
@@ -5547,6 +5813,46 @@ docs = ["furo (>=2024.1.29)"]
numpy = ["nptyping (>=2.5)"]
testing = ["covdefaults (>=2.3)", "coverage (>=7.4.4)", "defusedxml (>=0.7.1)", "diff-cover (>=9)", "pytest (>=8.1.1)", "pytest-cov (>=5)", "sphobjinv (>=2.3.1)", "typing-extensions (>=4.11)"]
+[[package]]
+name = "sphinx-autodoc-typehints"
+version = "3.0.1"
+description = "Type hints (PEP 484) support for the Sphinx autodoc extension"
+optional = true
+python-versions = ">=3.10"
+groups = ["main"]
+markers = "python_version == \"3.10\" and extra == \"docs\""
+files = [
+ {file = "sphinx_autodoc_typehints-3.0.1-py3-none-any.whl", hash = "sha256:4b64b676a14b5b79cefb6628a6dc8070e320d4963e8ff640a2f3e9390ae9045a"},
+ {file = "sphinx_autodoc_typehints-3.0.1.tar.gz", hash = "sha256:b9b40dd15dee54f6f810c924f863f9cf1c54f9f3265c495140ea01be7f44fa55"},
+]
+
+[package.dependencies]
+sphinx = ">=8.1.3"
+
+[package.extras]
+docs = ["furo (>=2024.8.6)"]
+testing = ["covdefaults (>=2.3)", "coverage (>=7.6.10)", "defusedxml (>=0.7.1)", "diff-cover (>=9.2.1)", "pytest (>=8.3.4)", "pytest-cov (>=6)", "sphobjinv (>=2.3.1.2)", "typing-extensions (>=4.12.2)"]
+
+[[package]]
+name = "sphinx-autodoc-typehints"
+version = "3.2.0"
+description = "Type hints (PEP 484) support for the Sphinx autodoc extension"
+optional = true
+python-versions = ">=3.11"
+groups = ["main"]
+markers = "python_version >= \"3.11\" and extra == \"docs\""
+files = [
+ {file = "sphinx_autodoc_typehints-3.2.0-py3-none-any.whl", hash = "sha256:884b39be23b1d884dcc825d4680c9c6357a476936e3b381a67ae80091984eb49"},
+ {file = "sphinx_autodoc_typehints-3.2.0.tar.gz", hash = "sha256:107ac98bc8b4837202c88c0736d59d6da44076e65a0d7d7d543a78631f662a9b"},
+]
+
+[package.dependencies]
+sphinx = ">=8.2"
+
+[package.extras]
+docs = ["furo (>=2024.8.6)"]
+testing = ["covdefaults (>=2.3)", "coverage (>=7.6.12)", "defusedxml (>=0.7.1)", "diff-cover (>=9.2.3)", "pytest (>=8.3.4)", "pytest-cov (>=6)", "sphobjinv (>=2.3.1.2)", "typing-extensions (>=4.12.2)"]
+
[[package]]
name = "sphinx-book-theme"
version = "1.1.4"
@@ -5713,7 +6019,7 @@ description = "Sphinx directive to add unselectable prompt"
optional = true
python-versions = ">=3.9,<4.0"
groups = ["main"]
-markers = "extra == \"docs\""
+markers = "python_version == \"3.9\" and extra == \"docs\""
files = [
{file = "sphinx_prompt-1.8.0-py3-none-any.whl", hash = "sha256:369ecc633f0711886f9b3a078c83264245be1adf46abeeb9b88b5519e4b51007"},
{file = "sphinx_prompt-1.8.0.tar.gz", hash = "sha256:47482f86fcec29662fdfd23e7c04ef03582714195d01f5d565403320084372ed"},
@@ -5724,6 +6030,50 @@ docutils = "*"
pygments = "*"
Sphinx = ">=7.0.0,<8.0.0"
+[[package]]
+name = "sphinx-prompt"
+version = "1.9.0"
+description = "Sphinx directive to add unselectable prompt"
+optional = true
+python-versions = ">=3.10"
+groups = ["main"]
+markers = "python_version == \"3.10\" and extra == \"docs\""
+files = [
+ {file = "sphinx_prompt-1.9.0-py3-none-any.whl", hash = "sha256:fd731446c03f043d1ff6df9f22414495b23067c67011cc21658ea8d36b3575fc"},
+ {file = "sphinx_prompt-1.9.0.tar.gz", hash = "sha256:471b3c6d466dce780a9b167d9541865fd4e9a80ed46e31b06a52a0529ae995a1"},
+]
+
+[package.dependencies]
+certifi = "*"
+docutils = "*"
+idna = "*"
+pygments = "*"
+Sphinx = ">=8.0.0,<9.0.0"
+urllib3 = "*"
+
+[[package]]
+name = "sphinx-prompt"
+version = "1.10.0"
+description = "Sphinx directive to add unselectable prompt"
+optional = true
+python-versions = ">=3.11"
+groups = ["main"]
+markers = "python_version >= \"3.11\" and extra == \"docs\""
+files = [
+ {file = "sphinx_prompt-1.10.0-py3-none-any.whl", hash = "sha256:d62f7a1aa346225d30222a271dc78997031204a5f199ce5006c14ece0d94b217"},
+ {file = "sphinx_prompt-1.10.0.tar.gz", hash = "sha256:23dca4c07ade840c9e87089d79d3499040fa524b3c422941427454e215fdd111"},
+]
+
+[package.dependencies]
+certifi = "*"
+docutils = "*"
+idna = "*"
+jinja2 = "*"
+pygments = "*"
+requests = "2.32.4"
+Sphinx = "*"
+urllib3 = "*"
+
[[package]]
name = "sphinx-sitemap"
version = "2.7.2"
@@ -6446,4 +6796,4 @@ docs = ["autodoc_pydantic", "cairosvg", "ipython", "jinja2", "jupyter", "myst-pa
[metadata]
lock-version = "2.1"
python-versions = ">=3.9,<3.13"
-content-hash = "57c3843c1a957443a78cc80fdc9aa971ee517c6ce16b33502b855bc6831132ab"
+content-hash = "61f8de578809c08cf788c95b63b78ae66d760c6eb911f730fb981dddb478959c"
diff --git a/pyproject.toml b/pyproject.toml
index 7e8e21082..252813644 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,12 +1,12 @@
[tool.poetry]
name = "flow360"
-version = "v25.7.4b0"
+version = "v25.8.0b3"
description = "Flow360 Python Client"
authors = ["Flexcompute "]
[tool.poetry.dependencies]
python = ">=3.9,<3.13"
-pydantic = ">=2.8"
+pydantic = ">=2.8,<2.12"
pytest = "^7.1.2"
click = "^8.1.3"
toml = "^0.10.2"
diff --git a/tests/data/00000000-0000-0000-0000-000000000000/results/Y_slicing_forceDistribution.csv b/tests/data/00000000-0000-0000-0000-000000000000/results/Y_slicing_forceDistribution.csv
index 376236a57..db8542487 100644
--- a/tests/data/00000000-0000-0000-0000-000000000000/results/Y_slicing_forceDistribution.csv
+++ b/tests/data/00000000-0000-0000-0000-000000000000/results/Y_slicing_forceDistribution.csv
@@ -1,302 +1,301 @@
-Y, stride, blk-1/leftWing_CFx_per_span, blk-1/leftWing_CFz_per_span, blk-1/leftWing_CMy_per_span, blk-1/fuselage_CFx_per_span, blk-1/fuselage_CFz_per_span, blk-1/fuselage_CMy_per_span, blk-1/rightWing_CFx_per_span, blk-1/rightWing_CFz_per_span, blk-1/rightWing_CMy_per_span,
--5.02480911811194, 0.0336108287175501, 0.000470342069085086, 0.00103238078908972, -0.00342322285934544, 0, 0, 0, 0, 0, 0,
--4.99119828939439, 0.0336108287175492, 0.000362101971174712, 0.00181757136676592, -0.00602176907056759, 0, 0, 0, 0, 0, 0,
--4.95758746067684, 0.0336108287175501, 0.000376491113837601, 0.00202188953519795, -0.00665895756788854, 0, 0, 0, 0, 0, 0,
--4.92397663195929, 0.0336108287175492, 0.000394150881463456, 0.00235658489057913, -0.00774397670429137, 0, 0, 0, 0, 0, 0,
--4.89036580324174, 0.0336108287175501, 0.000414592829617829, 0.00264489249078894, -0.00867606521181081, 0, 0, 0, 0, 0, 0,
--4.85675497452419, 0.0336108287175501, 0.000438611671262743, 0.00292053183000095, -0.00955796576713591, 0, 0, 0, 0, 0, 0,
--4.82314414580664, 0.0336108287175492, 0.00045678846648138, 0.0031176467402586, -0.0101764502108635, 0, 0, 0, 0, 0, 0,
--4.78953331708909, 0.0336108287175501, 0.000482217214101513, 0.00335921187334712, -0.0109333782004854, 0, 0, 0, 0, 0, 0,
--4.75592248837154, 0.0336108287175492, 0.000486861197416282, 0.00353310626586398, -0.0114738291947231, 0, 0, 0, 0, 0, 0,
--4.72231165965399, 0.0336108287175501, 0.000514495320204574, 0.00369435655264916, -0.0119750026844012, 0, 0, 0, 0, 0, 0,
--4.68870083093644, 0.0336108287175501, 0.000535274543364942, 0.00382555144031057, -0.0123712507360623, 0, 0, 0, 0, 0, 0,
--4.65509000221889, 0.0336108287175492, 0.000540852495813529, 0.00404071836259213, -0.0130287196953067, 0, 0, 0, 0, 0, 0,
--4.62147917350134, 0.0336108287175501, 0.00054755267245778, 0.00420365386667665, -0.0135076607900848, 0, 0, 0, 0, 0, 0,
--4.58786834478379, 0.0336108287175492, 0.00056271448641277, 0.00425533684425497, -0.0136447089417762, 0, 0, 0, 0, 0, 0,
--4.55425751606624, 0.0336108287175501, 0.000581629055420937, 0.00431204028336554, -0.0137954877702383, 0, 0, 0, 0, 0, 0,
--4.52064668734869, 0.0336108287175501, 0.000606691518199799, 0.00449839605135145, -0.0143389425765172, 0, 0, 0, 0, 0, 0,
--4.48703585863114, 0.0336108287175492, 0.000602774798570121, 0.00471597383385303, -0.0150085286051228, 0, 0, 0, 0, 0, 0,
--4.45342502991359, 0.0336108287175501, 0.000607414158235875, 0.00478329146348846, -0.0151772712376839, 0, 0, 0, 0, 0, 0,
--4.41981420119604, 0.0336108287175492, 0.000614045639523713, 0.00474575078113951, -0.0149982132388319, 0, 0, 0, 0, 0, 0,
--4.38620337247849, 0.0336108287175501, 0.000638363428146611, 0.00479763190687746, -0.0151163564256402, 0, 0, 0, 0, 0, 0,
--4.35259254376094, 0.0336108287175501, 0.000658758382703111, 0.00500556886621821, -0.0157392228732739, 0, 0, 0, 0, 0, 0,
--4.31898171504339, 0.0336108287175492, 0.000657925453700662, 0.00525031420071902, -0.0164728486047162, 0, 0, 0, 0, 0, 0,
--4.28537088632584, 0.0336108287175501, 0.000651207145230702, 0.00527579747046633, -0.0165023630083622, 0, 0, 0, 0, 0, 0,
--4.25176005760829, 0.0336108287175492, 0.000659412235364163, 0.00521462905099333, -0.0162461521112712, 0, 0, 0, 0, 0, 0,
--4.21814922889074, 0.0336108287175501, 0.000690659748337728, 0.00524510955130831, -0.016303422893511, 0, 0, 0, 0, 0, 0,
--4.18453840017319, 0.0336108287175501, 0.000708927328460372, 0.00539123344851971, -0.0167132019731698, 0, 0, 0, 0, 0, 0,
--4.15092757145564, 0.0336108287175492, 0.000710262997352751, 0.00559233441011727, -0.0173132795758063, 0, 0, 0, 0, 0, 0,
--4.1173167427381, 0.0336108287175501, 0.000701354950102389, 0.00567108631375586, -0.0174863358624779, 0, 0, 0, 0, 0, 0,
--4.08370591402054, 0.0336108287175501, 0.000713283411108443, 0.0055787533601711, -0.0171449216908451, 0, 0, 0, 0, 0, 0,
--4.050095085303, 0.0336108287175492, 0.000724184003262914, 0.00560560750742869, -0.0171769752318999, 0, 0, 0, 0, 0, 0,
--4.01648425658545, 0.0336108287175501, 0.000744158756772779, 0.0056956740714217, -0.0174084355303933, 0, 0, 0, 0, 0, 0,
--3.9828734278679, 0.0336108287175492, 0.000756948689541568, 0.00587001502099072, -0.0179167398699708, 0, 0, 0, 0, 0, 0,
--3.94926259915035, 0.0336108287175501, 0.000755888043559875, 0.00597457216989749, -0.0181800402378501, 0, 0, 0, 0, 0, 0,
--3.9156517704328, 0.0336108287175496, 0.000766333428334696, 0.00594136639966439, -0.0179952590826619, 0, 0, 0, 0, 0, 0,
--3.88204094171525, 0.0336108287175496, 0.000769668244876786, 0.00601284546519374, -0.0181400398352559, 0, 0, 0, 0, 0, 0,
--3.8484301129977, 0.0336108287175501, 0.000774373404198371, 0.00606979789156753, -0.0182957894000435, 0, 0, 0, 0, 0, 0,
--3.81481928428015, 0.0336108287175492, 0.00079605063775158, 0.00610016173445085, -0.0183722272357467, 0, 0, 0, 0, 0, 0,
--3.7812084555626, 0.0336108287175501, 0.000817913063597549, 0.00618991763491073, -0.0185574250642031, 0, 0, 0, 0, 0, 0,
--3.74759762684505, 0.0336108287175496, 0.000822171341610529, 0.00628302968108633, -0.0187488155732106, 0, 0, 0, 0, 0, 0,
--3.7139867981275, 0.0336108287175496, 0.000807645786937011, 0.00632360536570551, -0.01883346001754, 0, 0, 0, 0, 0, 0,
--3.68037596940995, 0.0336108287175501, 0.000797251662914596, 0.00631005826265415, -0.0187808018827367, 0, 0, 0, 0, 0, 0,
--3.6467651406924, 0.0336108287175492, 0.000830158102326298, 0.00638006413788986, -0.0188994074471788, 0, 0, 0, 0, 0, 0,
--3.61315431197485, 0.0336108287175501, 0.000854775705064869, 0.00642716256974645, -0.0189750056982955, 0, 0, 0, 0, 0, 0,
--3.5795434832573, 0.0336108287175496, 0.000866460105892051, 0.00649738796388195, -0.0191496366931394, 0, 0, 0, 0, 0, 0,
--3.54593265453975, 0.0336108287175496, 0.000857116261757694, 0.00658625552872327, -0.0193652250512742, 0, 0, 0, 0, 0, 0,
--3.5123218258222, 0.0336108287175501, 0.000852476646348691, 0.00672074875349641, -0.0196802578473927, 0, 0, 0, 0, 0, 0,
--3.47871099710465, 0.0336108287175492, 0.000873208288158644, 0.00661877883934512, -0.0193137965869612, 0, 0, 0, 0, 0, 0,
--3.4451001683871, 0.0336108287175501, 0.000882090874798987, 0.00665895477357414, -0.0193901421215276, 0, 0, 0, 0, 0, 0,
--3.41148933966955, 0.0336108287175496, 0.000897684904724819, 0.00669691595680408, -0.0194628582783844, 0, 0, 0, 0, 0, 0,
--3.377878510952, 0.0336108287175496, 0.000904842420806997, 0.00669444031170763, -0.0194170746235569, 0, 0, 0, 0, 0, 0,
--3.34426768223445, 0.0336108287175501, 0.000905357981392678, 0.0068270194538437, -0.0197369919760578, 0, 0, 0, 0, 0, 0,
--3.3106568535169, 0.0336108287175492, 0.000908281142853451, 0.00690959596123263, -0.0198909495173054, 0, 0, 0, 0, 0, 0,
--3.27704602479935, 0.0336108287175501, 0.000934963453157417, 0.00678303173377931, -0.0194718453456042, 0, 0, 0, 0, 0, 0,
--3.2434351960818, 0.0336108287175496, 0.000949010818600616, 0.00697284398786486, -0.0199858349863505, 0, 0, 0, 0, 0, 0,
--3.20982436736425, 0.0336108287175496, 0.000945136743958943, 0.00713526370893061, -0.0203878228622526, 0, 0, 0, 0, 0, 0,
--3.1762135386467, 0.0336108287175501, 0.000953754029838007, 0.00696813524685288, -0.0198371605875549, 0, 0, 0, 0, 0, 0,
--3.14260270992915, 0.0336108287175492, 0.000952921175505775, 0.00694666712035129, -0.0197588681067106, 0, 0, 0, 0, 0, 0,
--3.1089918812116, 0.0336108287175501, 0.00097281022000244, 0.0070759605759123, -0.02004164184275, 0, 0, 0, 0, 0, 0,
--3.07538105249405, 0.0336108287175496, 0.000991896690665328, 0.00716333602044201, -0.0201876481115592, 0, 0, 0, 0, 0, 0,
--3.0417702237765, 0.0336108287175496, 0.000985775982014034, 0.0072653557152692, -0.02047478800359, 0, 0, 0, 0, 0, 0,
--3.00815939505896, 0.0336108287175496, 0.000987536408608706, 0.0072757890471121, -0.0204404231692442, 0, 0, 0, 0, 0, 0,
--2.97454856634141, 0.0336108287175501, 0.000998078260422, 0.00712110021801566, -0.0198959297815731, 0, 0, 0, 0, 0, 0,
--2.94093773762386, 0.0336108287175496, 0.00101564901717352, 0.00725510941352889, -0.0202597601455607, 0, 0, 0, 0, 0, 0,
--2.90732690890631, 0.0336108287175496, 0.00103857508681841, 0.00738166911959137, -0.0205851395897454, 0, 0, 0, 0, 0, 0,
--2.87371608018876, 0.0336108287175496, 0.00103399456692514, 0.00726282911727265, -0.0202034025238506, 0, 0, 0, 0, 0, 0,
--2.84010525147121, 0.0336108287175496, 0.00103125557097051, 0.00736581703692448, -0.0203842131828331, 0, 0, 0, 0, 0, 0,
--2.80649442275366, 0.0336108287175501, 0.00106180188256424, 0.00734875945673505, -0.0202717102732545, 0, 0, 0, 0, 0, 0,
--2.77288359403611, 0.0336108287175496, 0.00106979145976391, 0.00733817558994017, -0.0202102697643673, 0, 0, 0, 0, 0, 0,
--2.73927276531856, 0.0336108287175496, 0.00106341251216901, 0.0075273025165534, -0.0207291335042787, 0, 0, 0, 0, 0, 0,
--2.70566193660101, 0.0336108287175496, 0.0010925033814807, 0.00758432668377364, -0.0207661674515815, 0, 0, 0, 0, 0, 0,
--2.67205110788346, 0.0336108287175496, 0.00109333949327935, 0.00748033255766922, -0.020401835622955, 0, 0, 0, 0, 0, 0,
--2.63844027916591, 0.0336108287175501, 0.00110131276862917, 0.00745455851155809, -0.0203186012643432, 0, 0, 0, 0, 0, 0,
--2.60482945044836, 0.0336108287175496, 0.00112527347610686, 0.00742950828255858, -0.020226689207063, 0, 0, 0, 0, 0, 0,
--2.57121862173081, 0.0336108287175496, 0.00111921424801135, 0.00764616700805331, -0.0207258358004737, 0, 0, 0, 0, 0, 0,
--2.53760779301326, 0.0336108287175496, 0.00113855850645745, 0.00771141152423503, -0.0208268836589157, 0, 0, 0, 0, 0, 0,
--2.50399696429571, 0.0336108287175496, 0.00115923400841705, 0.00763250124657736, -0.020566107342115, 0, 0, 0, 0, 0, 0,
--2.47038613557816, 0.0336108287175501, 0.00114971110961475, 0.00752145784467611, -0.0202395340125134, 0, 0, 0, 0, 0, 0,
--2.43677530686061, 0.0336108287175496, 0.00115844753654206, 0.00766401975274633, -0.0205108563846049, 0, 0, 0, 0, 0, 0,
--2.40316447814306, 0.0336108287175496, 0.00119285039212218, 0.0077023585316285, -0.0205781521743038, 0, 0, 0, 0, 0, 0,
--2.36955364942551, 0.0336108287175496, 0.00119044801875096, 0.00769784096052404, -0.0205626179896279, 0, 0, 0, 0, 0, 0,
--2.33594282070796, 0.0336108287175496, 0.00120272371277573, 0.00779091756633651, -0.0207139666696694, 0, 0, 0, 0, 0, 0,
--2.30233199199041, 0.0336108287175501, 0.001222469162198, 0.00778278310910058, -0.0205964569920043, 0, 0, 0, 0, 0, 0,
--2.26872116327286, 0.0336108287175496, 0.00123232778897561, 0.00769450751797757, -0.0203566758789452, 0, 0, 0, 0, 0, 0,
--2.23511033455531, 0.0336108287175496, 0.00122982267047178, 0.00765864159658575, -0.0202273846618541, 0, 0, 0, 0, 0, 0,
--2.20149950583776, 0.0336108287175496, 0.00123741196744043, 0.00781125191492394, -0.0205551421450367, 0, 0, 0, 0, 0, 0,
--2.16788867712021, 0.0336108287175496, 0.00125190644686348, 0.00780680988740199, -0.0204733752850057, 0, 0, 0, 0, 0, 0,
--2.13427784840266, 0.0336108287175501, 0.00126375908398306, 0.00781933643051637, -0.0204726283846625, 0, 0, 0, 0, 0, 0,
--2.10066701968511, 0.0336108287175496, 0.00128884559558024, 0.00774845043754225, -0.0202521896328338, 0, 0, 0, 0, 0, 0,
--2.06705619096756, 0.0336108287175496, 0.00129868404187919, 0.00770613854815638, -0.0200806506261936, 0, 0, 0, 0, 0, 0,
--2.03344536225001, 0.0336108287175496, 0.00130858184307318, 0.00782481984628942, -0.0203463582979411, 0, 0, 0, 0, 0, 0,
--1.99983453353246, 0.0336108287175496, 0.00133794879094756, 0.00795541567209259, -0.0206360111316986, 0, 0, 0, 0, 0, 0,
--1.96622370481491, 0.0336108287175501, 0.00132860675623339, 0.00782236483374132, -0.0202121717044733, 0, 0, 0, 0, 0, 0,
--1.93261287609736, 0.0336108287175496, 0.00132630083908833, 0.00779785337786681, -0.0201191823440913, 0, 0, 0, 0, 0, 0,
--1.89900204737981, 0.0336108287175496, 0.00137421435218484, 0.00779611113773535, -0.0200990332179782, 0, 0, 0, 0, 0, 0,
--1.86539121866227, 0.0336108287175496, 0.00138723993619545, 0.00785782587072532, -0.0201722190808958, 0, 0, 0, 0, 0, 0,
--1.83178038994472, 0.0336108287175501, 0.00138321590134603, 0.00797230135846759, -0.0203996565739487, 0, 0, 0, 0, 0, 0,
--1.79816956122717, 0.0336108287175496, 0.0013924119319497, 0.00789813408290209, -0.0201493742895832, 0, 0, 0, 0, 0, 0,
--1.76455873250962, 0.0336108287175496, 0.00140005662757185, 0.00779194470231723, -0.0199045737124004, 0, 0, 0, 0, 0, 0,
--1.73094790379207, 0.0336108287175496, 0.00143539942695382, 0.00785925641054603, -0.0199986023935606, 0, 0, 0, 0, 0, 0,
--1.69733707507452, 0.0336108287175496, 0.00144170880708726, 0.00789419336667183, -0.0199870098203634, 0, 0, 0, 0, 0, 0,
--1.66372624635697, 0.0336108287175501, 0.00144764287991371, 0.00790255600308674, -0.0199826465766543, 0, 0, 0, 0, 0, 0,
--1.63011541763942, 0.0336108287175496, 0.00145614993003944, 0.00787968494840595, -0.0199490020841511, 0, 0, 0, 0, 0, 0,
--1.59650458892187, 0.0336108287175496, 0.00146632564901676, 0.00781445057818542, -0.019705258944971, 0, 0, 0, 0, 0, 0,
--1.56289376020432, 0.0336108287175496, 0.0015025651695416, 0.00788479723666074, -0.0198013295571375, 0, 0, 0, 0, 0, 0,
--1.52928293148677, 0.0336108287175496, 0.00150437164778609, 0.0078849846748871, -0.0197459147578864, 0, 0, 0, 0, 0, 0,
--1.49567210276922, 0.0336108287175501, 0.00151981777970998, 0.00782044786084702, -0.0196133459027264, 0, 0, 0, 0, 0, 0,
--1.46206127405167, 0.0336108287175496, 0.00153235370142524, 0.00775175459542972, -0.0194590517795927, 0, 0, 0, 0, 0, 0,
--1.42845044533412, 0.0336108287175496, 0.0015394495255789, 0.0078019204894776, -0.0194482054070609, 0, 0, 0, 0, 0, 0,
--1.39483961661657, 0.0336108287175496, 0.0015561514563158, 0.00788588886749136, -0.0196046201889257, 0, 0, 0, 0, 0, 0,
--1.36122878789902, 0.0336108287175496, 0.0015783049350126, 0.00780974040213685, -0.0194151691933048, 0, 0, 0, 0, 0, 0,
--1.32761795918147, 0.0336108287175501, 0.00159555806297675, 0.00775768026346238, -0.0192690876723052, 0, 0, 0, 0, 0, 0,
--1.29400713046392, 0.0336108287175496, 0.00159102129817719, 0.00776965519256371, -0.0192017636794929, 0, 0, 0, 0, 0, 0,
--1.26039630174637, 0.0336108287175496, 0.00160955752388377, 0.00778771274845467, -0.0192082135716504, 0, 0, 0, 0, 0, 0,
--1.22678547302882, 0.0336108287175496, 0.00162045973487659, 0.00775459020583298, -0.0191509342645377, 0, 0, 0, 0, 0, 0,
--1.19317464431127, 0.0336108287175496, 0.00163691218818199, 0.00771595275404383, -0.0190730785963991, 0, 0, 0, 0, 0, 0,
--1.15956381559372, 0.0336108287175501, 0.00164831212067262, 0.00759349148024402, -0.0187108703975719, 0, 0, 0, 0, 0, 0,
--1.12595298687617, 0.0336108287175496, 0.00166692051872794, 0.00766460952556926, -0.0187825756191075, 0, 0, 0, 0, 0, 0,
--1.09234215815862, 0.0336108287175496, 0.00168353629213769, 0.00761499398469513, -0.0186729252629671, 0, 0, 0, 0, 0, 0,
--1.05873132944107, 0.0336108287175496, 0.0016867597699769, 0.00763581103023003, -0.0186828439538057, 0, 0, 0, 0, 0, 0,
--1.02512050072352, 0.0336108287175496, 0.00170157959051467, 0.00764408641278503, -0.0186731076120015, 0, 0, 0, 0, 0, 0,
--0.991509672005973, 0.0336108287175501, 0.00173830688951988, 0.00749127301477849, -0.0183330131066813, 0, 0, 0, 0, 0, 0,
--0.957898843288423, 0.0336108287175492, 0.00173532899257238, 0.00733799511155013, -0.017968433015858, 0, 0, 0, 0, 0, 0,
--0.924288014570874, 0.0336108287175501, 0.00173801003312147, 0.00744800017566516, -0.0181378622680674, 0, 0, 0, 0, 0, 0,
--0.890677185853324, 0.0336108287175501, 0.00175015108657065, 0.00752168284392443, -0.0182638589846718, 0, 0, 0, 0, 0, 0,
--0.857066357135774, 0.0336108287175492, 0.00176397133792544, 0.00736837608198434, -0.0179434463952251, 0, 0, 0, 0, 0, 0,
--0.823455528418224, 0.0336108287175501, 0.00179068613424831, 0.00725750363854718, -0.0177095582962837, 0, 0, 0, 0, 0, 0,
--0.789844699700675, 0.0336108287175492, 0.00180343927001596, 0.00724320755156654, -0.0176379317505828, 0, 0, 0, 0, 0, 0,
--0.756233870983125, 0.0336108287175501, 0.00179307792973748, 0.00726034016911441, -0.0175767358589, 0, 0, 0, 0, 0, 0,
--0.722623042265575, 0.0336108287175501, 0.00181853467582665, 0.0072073272196075, -0.0175035782583683, 0, 0, 0, 0, 0, 0,
--0.689012213548025, 0.0336108287175492, 0.00181485131493534, 0.00706043781231928, -0.0171595991578281, 0, 0, 0, 0, 0, 0,
--0.655401384830476, 0.0336108287175501, 0.00182612941102705, 0.00695237605950437, -0.016924948825101, 0, 0, 0, 0, 0, 0,
--0.621790556112926, 0.0336108287175492, 0.00186181022139975, 0.00700901765118897, -0.0170511081968599, 0, 0, 0, 0, 0, 0,
--0.588179727395377, 0.0336108287175501, 0.00189219709352808, 0.00703653121385452, -0.0170736889728561, 0, 0, 0, 0, 0, 0,
--0.554568898677827, 0.0336108287175501, 0.00192816156367794, 0.00705332004140741, -0.0169818738737471, 0, 0, 0, 0, 0, 0,
--0.520958069960277, 0.0336108287175492, 0.00199291431521547, 0.0070836232866573, -0.0169386085613413, 0, 0, 0, 0, 0, 0,
--0.487347241242727, 0.0336108287175501, 0.00198936049994366, 0.00692912012051487, -0.0167529927045854, 0, 0, 0, 0, 0, 0,
--0.453736412525178, 0.0336108287175492, 0.00133909886998168, 0.0085312357507783, -0.018879710870759, 0.000994059388997029, -0.00156582507391184, 0.00217264156016244, 0, 0, 0,
--0.420125583807628, 0.0336108287175501, 0.00109688839889628, 0.00937705002837353, -0.0200777135912791, 0.00225728591051082, -0.00206038772004637, 0.0030210375693217, 0, 0, 0,
--0.386514755090078, 0.0336108287175501, 0.000870203832061572, 0.00831167626315296, -0.0184040574902797, 0.00357243027893747, -0.000924825221313489, 0.00138737591283402, 0, 0, 0,
--0.352903926372528, 0.0336108287175492, 0.000145645121735092, 0.00237028281712212, -0.00530980523191098, 0.00657591401614288, 0.00596432663647871, -0.0140834102736749, 0, 0, 0,
--0.319293097654979, 0.0336108287175501, 0, 0, 0, 0.00609186538634942, 0.00766361018796394, -0.0179567935813004, 0, 0, 0,
--0.285682268937429, 0.0336108287175492, 0, 0, 0, 0.00553086721357205, 0.00730832017413336, -0.0174159869710206, 0, 0, 0,
--0.25207144021988, 0.0336108287175501, 0, 0, 0, 0.00505976086611972, 0.0073108188378456, -0.0172766114750593, 0, 0, 0,
--0.21846061150233, 0.0336108287175501, 0, 0, 0, 0.00465378728122627, 0.00690634031000821, -0.0164649758033445, 0, 0, 0,
--0.18484978278478, 0.0336108287175492, 0, 0, 0, 0.00439602416682022, 0.00701430627933367, -0.0168112416188375, 0, 0, 0,
--0.15123895406723, 0.0336108287175501, 0, 0, 0, 0.0042113118484406, 0.00675045971654009, -0.016273303175627, 0, 0, 0,
--0.117628125349681, 0.0336108287175492, 0, 0, 0, 0.00420309692930225, 0.00676331910239671, -0.0162665439832169, 0, 0, 0,
--0.0840172966321311, 0.0336108287175501, 0, 0, 0, 0.00445754758930279, 0.0068382721991199, -0.0163399251311339, 0, 0, 0,
--0.050406467914581, 0.0336108287175501, 0, 0, 0, 0.0053876414419872, 0.00666533085251443, -0.0160331864400831, 0, 0, 0,
--0.0167956391970314, 0.0336108287175492, 0, 0, 0, 0.00735624820146298, 0.0067407057796704, -0.0161515946515056, 0, 0, 0,
-0.0168151895205182, 0.0336108287175501, 0, 0, 0, 0.00736559426919886, 0.00671489568372628, -0.0161576272981709, 0, 0, 0,
-0.0504260182380678, 0.0336108287175492, 0, 0, 0, 0.00536893279283081, 0.0066618698623847, -0.0160125930502119, 0, 0, 0,
-0.0840368469556174, 0.0336108287175501, 0, 0, 0, 0.00445126089931289, 0.00680570172415461, -0.0163202199309463, 0, 0, 0,
-0.117647675673167, 0.0336108287175501, 0, 0, 0, 0.0042000717878732, 0.00676934738796828, -0.0162866072735308, 0, 0, 0,
-0.151258504390717, 0.0336108287175492, 0, 0, 0, 0.00419324414368048, 0.00679724469199551, -0.0162087297971945, 0, 0, 0,
-0.184869333108267, 0.0336108287175501, 0, 0, 0, 0.00441073779476435, 0.00708375503347185, -0.0169053175592189, 0, 0, 0,
-0.218480161825816, 0.0336108287175492, 0, 0, 0, 0.00465959016962243, 0.00677396812305508, -0.0162911519791666, 0, 0, 0,
-0.252090990543366, 0.0336108287175501, 0, 0, 0, 0.00507062929643877, 0.00731757824487935, -0.0172320059156236, 0, 0, 0,
-0.285701819260916, 0.0336108287175501, 0, 0, 0, 0.00554406479628231, 0.00713759748122594, -0.0170746470201541, 0, 0, 0,
-0.319312647978466, 0.0336108287175492, 0, 0, 0, 0.00607644567741382, 0.00779816822526878, -0.0181329029801268, 0, 0, 0,
-0.352923476696015, 0.0336108287175501, 0, 0, 0, 0.00658258057901175, 0.00577781433454318, -0.0137846479531657, 0.000146979768036774, 0.00237678859810206, -0.00532307297939396,
-0.386534305413565, 0.0336108287175492, 0, 0, 0, 0.00354220589740535, -0.000790527818333227, 0.00114192131560859, 0.000864413264209846, 0.0082521898270149, -0.0182502133186208,
-0.420145134131114, 0.0336108287175501, 0, 0, 0, 0.00227115036478823, -0.00208835592089667, 0.00307438800950459, 0.00109343881882253, 0.00935602035565083, -0.0200157741402774,
-0.453755962848664, 0.0336108287175501, 0, 0, 0, 0.00101093671190196, -0.0015624292568078, 0.00217303408846517, 0.00134915800521793, 0.00853134441804222, -0.0188497803087169,
-0.487366791566214, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00199296466135107, 0.00675254899530676, -0.0163691944175357,
-0.520977620283764, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00200432124703397, 0.00699443206858486, -0.0167617214052806,
-0.554588449001313, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00193895358143152, 0.00709136752275001, -0.0170306491505563,
-0.588199277718863, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00189761961696624, 0.00699930446565475, -0.016949481163091,
-0.621810106436413, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00185857584255041, 0.00696111694783956, -0.0169164372668222,
-0.655420935153963, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00183400553433561, 0.00703373030573242, -0.0170841339127339,
-0.689031763871512, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.0018321231755656, 0.00707209074026941, -0.0172044115651456,
-0.722642592589062, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00182069957957905, 0.00717799588263588, -0.017440632978983,
-0.756253421306611, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00180965985184215, 0.00722434797781003, -0.0175373107318701,
-0.789864250024161, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00178846582444991, 0.00722885234205631, -0.0175866345675876,
-0.823475078741711, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00177215502338515, 0.00730804022248511, -0.0177848197731383,
-0.857085907459261, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00177411093483938, 0.00730371258195732, -0.0177774006853496,
-0.89069673617681, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00176380111720723, 0.00747243476874846, -0.0181646013001,
-0.92430756489436, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00174445881399173, 0.00749764704395638, -0.0182852086498043,
-0.95791839361191, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.0017297039410833, 0.00746076656929297, -0.0182432030015476,
-0.99152922232946, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00171419794539665, 0.00753301379878302, -0.0184148574884143,
-1.02514005104701, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.0017171028562533, 0.00758486997756415, -0.0185546512275568,
-1.05875087976456, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00170633450129727, 0.00751021685163381, -0.0184339713579645,
-1.09236170848211, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00167357093351958, 0.00761126706614621, -0.0186749648489443,
-1.12597253719966, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00166678001788129, 0.00763374984857316, -0.0187880817720613,
-1.15958336591721, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00164833920287982, 0.00772235687851386, -0.0189632161454164,
-1.19319419463476, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00164422534206491, 0.00771479553940106, -0.0189969663306115,
-1.22680502335231, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00163273526793667, 0.00773238211626325, -0.0190847623329428,
-1.26041585206986, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00162175730774744, 0.00774184369330461, -0.0191319320511265,
-1.29402668078741, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00160325769583, 0.00776857214777246, -0.0192623442128681,
-1.32763750950496, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.0015764332804939, 0.00776270134357302, -0.0192771850956167,
-1.36124833822251, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00157425727010903, 0.00777545960607258, -0.019303213949886,
-1.39485916694006, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00155737071172632, 0.00783358218786056, -0.0195101954232277,
-1.42846999565761, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00154513351409666, 0.00783150824955357, -0.0195214585898279,
-1.46208082437516, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.001527203828287, 0.00779237851516276, -0.0194853152571177,
-1.49569165309271, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.0015052986112418, 0.00776846121968105, -0.019463482086854,
-1.52930248181025, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00151043341861451, 0.00789337336906524, -0.0198444713838909,
-1.5629133105278, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00151183788390668, 0.00785586680553428, -0.0197601109064352,
-1.59652413924535, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00148039266638568, 0.00786298294667155, -0.0198162818666707,
-1.6301349679629, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00144588378269087, 0.00786716175651594, -0.0198589844572888,
-1.66374579668045, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00142779951652779, 0.00785606998006967, -0.0198790728308313,
-1.697356625398, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00144177433046979, 0.00794982448019128, -0.0201340579501163,
-1.73096745411555, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00143625384017713, 0.00797340360714148, -0.0202673129962929,
-1.7645782828331, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.0014139195809966, 0.00776076525724547, -0.0198358940251357,
-1.79818911155065, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00138049676000345, 0.00777485988215951, -0.0199001628192384,
-1.8317999402682, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00137098152394187, 0.00782921058601074, -0.0200404982292042,
-1.86541076898575, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00138348238162994, 0.00794890361180001, -0.0203385591835833,
-1.8990215977033, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00138060187199278, 0.00796158444794812, -0.0204667171882689,
-1.93263242642085, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00137240247529101, 0.00782660963167805, -0.0202540562141501,
-1.9662432551384, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00133218263029819, 0.00772229466604732, -0.020013335496107,
-1.99985408385595, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00130271933573658, 0.00783314291578209, -0.0202993189031666,
-2.0334649125735, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.0013033830746339, 0.00781963431960125, -0.0203056555644486,
-2.06707574129105, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00131457164387243, 0.00784971845931837, -0.0204787211014001,
-2.1006865700086, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00129875950788775, 0.00782825861034154, -0.0204760605362472,
-2.13429739872615, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00126976075075216, 0.00779101820331443, -0.0204285215275307,
-2.1679082274437, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00125611838874534, 0.00776996097994982, -0.0204039653670678,
-2.20151905616125, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00124734279425741, 0.00772432216131663, -0.0203187940097723,
-2.2351298848788, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.001226403656632, 0.00774053552281337, -0.0204032735465057,
-2.26874071359635, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00122794609587348, 0.00780790495670122, -0.0206573537394514,
-2.3023515423139, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00122766922606352, 0.00781366451226181, -0.0207624264614457,
-2.33596237103145, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00120130291037364, 0.0077090337245075, -0.0205198143176916,
-2.369573199749, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00117165835371223, 0.00766201056067202, -0.0204035509436555,
-2.40318402846655, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00118007690958911, 0.00756840656150893, -0.0202285032670991,
-2.4367948571841, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00117208814309608, 0.00763418502046047, -0.0204841378907732,
-2.47040568590165, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00116905774039806, 0.00765512130439508, -0.020574491924834,
-2.5040165146192, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.0011488538364919, 0.0076640842177089, -0.0206743054873847,
-2.53762734333675, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00113665465106545, 0.00766735753148298, -0.0206972616325749,
-2.5712381720543, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00112312464198117, 0.00757841949775475, -0.0205195746413504,
-2.60484900077185, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00111076168345014, 0.00750755202617586, -0.0203850656597508,
-2.6384598294894, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00110509596312147, 0.00758736776004868, -0.0206881159432184,
-2.67207065820694, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00110125893222163, 0.00744064140191101, -0.0203498187027332,
-2.70568148692449, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00107384293779697, 0.00739998876072871, -0.0202798533490166,
-2.73929231564204, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00107739104988549, 0.00746674062308083, -0.0204986566160364,
-2.77290314435959, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00106931045831918, 0.00739935684404182, -0.0203760427850539,
-2.80651397307714, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00106825651565179, 0.00740614841865683, -0.0204561557525441,
-2.84012480179469, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00104721868161754, 0.00743889598874306, -0.0206000311358696,
-2.87373563051224, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00103894807896862, 0.00724846711029415, -0.0201515512696662,
-2.90734645922979, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00101893703689658, 0.00725213431256654, -0.0201775715985403,
-2.94095728794734, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00101412980038703, 0.00737500971589565, -0.0205592111424079,
-2.97456811666489, 0.0336108287175501, 0, 0, 0, 0, 0, 0, 0.00101595923706723, 0.00721829340521934, -0.0202192744885957,
-3.00817894538244, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000999616790013093, 0.00717525960911597, -0.020168729096729,
-3.04178977409999, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000988016502640846, 0.00718149573442461, -0.0202284382135002,
-3.07540060281754, 0.0336108287175509, 0, 0, 0, 0, 0, 0, 0.000978743232580044, 0.00701636858484985, -0.0198129033828883,
-3.10901143153509, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000971241228124182, 0.00711555002625144, -0.0201346143182136,
-3.14262226025264, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000980989856665957, 0.00712259100955782, -0.0202434430828845,
-3.17623308897019, 0.0336108287175509, 0, 0, 0, 0, 0, 0, 0.000955501307720116, 0.00691456941105626, -0.0197146909055606,
-3.20984391768774, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000928246337497822, 0.00701886686369715, -0.0200683170714679,
-3.24345474640529, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000925478319551151, 0.0069200833869479, -0.01981750569535,
-3.27706557512284, 0.0336108287175509, 0, 0, 0, 0, 0, 0, 0.000926644255603628, 0.00683088110167545, -0.0196114495074449,
-3.31067640384039, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000924131878408122, 0.00696093297578957, -0.0200475956342751,
-3.34428723255794, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000920032891571761, 0.00682804807610617, -0.0197381294828238,
-3.37789806127549, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00089654597875992, 0.00666839780413866, -0.0193247260378686,
-3.41150888999304, 0.0336108287175509, 0, 0, 0, 0, 0, 0, 0.000892196283708366, 0.00674857677816546, -0.0195907986696127,
-3.44511971871059, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000889081858986641, 0.00664931627517708, -0.019356184464472,
-3.47873054742814, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000884520005796175, 0.00665569881591357, -0.0194388211064622,
-3.51234137614569, 0.0336108287175509, 0, 0, 0, 0, 0, 0, 0.000869451921422794, 0.00669631997745908, -0.0196266934134537,
-3.54595220486324, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000854857671532409, 0.00648968431871053, -0.0190756548507772,
-3.57956303358079, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000848792667282477, 0.00633768383281939, -0.0186808283392997,
-3.61317386229834, 0.0336108287175509, 0, 0, 0, 0, 0, 0, 0.000835695827027305, 0.00636922496456482, -0.0187855255170522,
-3.64678469101589, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000846010718316075, 0.00637569686779853, -0.0189040812365089,
-3.68039551973344, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000828934484469618, 0.00647338403885935, -0.0192646519397086,
-3.71400634845099, 0.0336108287175509, 0, 0, 0, 0, 0, 0, 0.000816899433681252, 0.00630819315157258, -0.0188217975131524,
-3.74761717716854, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000815739451536889, 0.00608384978247865, -0.0181529592523646,
-3.78122800588608, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000791812870613611, 0.00606811231883676, -0.0181605505449549,
-3.81483883460363, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000783295074291402, 0.00620936747727471, -0.0186569602328132,
-3.84844966332118, 0.0336108287175509, 0, 0, 0, 0, 0, 0, 0.000783839653978096, 0.00620640730470964, -0.0187286064463301,
-3.88206049203873, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000771296752712827, 0.00603752650003367, -0.018247482991572,
-3.91567132075628, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000769397367718439, 0.00584327139072089, -0.0177002328575141,
-3.94928214947383, 0.0336108287175509, 0, 0, 0, 0, 0, 0, 0.000743494228050792, 0.005794028990961, -0.0175860271336008,
-3.98289297819138, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00074677157514738, 0.00584187049813201, -0.0178039531616003,
-4.01650380690893, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000749163549612672, 0.00588627244111973, -0.018013443043878,
-4.05011463562648, 0.0336108287175509, 0, 0, 0, 0, 0, 0, 0.000730877009745045, 0.0057363025000965, -0.0175920563365922,
-4.08372546434403, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00072587739443037, 0.005553433126148, -0.0170648682893953,
-4.11733629306158, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000710309980966556, 0.00554579289417955, -0.0170829807748559,
-4.15094712177913, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000698916545840121, 0.00547419877928839, -0.0169237493033087,
-4.18455795049668, 0.0336108287175509, 0, 0, 0, 0, 0, 0, 0.000709581090122893, 0.00546998703505875, -0.0169635405550825,
-4.21816877921423, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000680431061993081, 0.00536648860695189, -0.0166819048146616,
-4.25177960793178, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00067607578434899, 0.00521768182116309, -0.016299552189573,
-4.28539043664933, 0.0336108287175509, 0, 0, 0, 0, 0, 0, 0.000674211611110797, 0.0051238595639798, -0.016025327132935,
-4.31900126536688, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.00065294571280469, 0.00500326319828527, -0.0156586224954281,
-4.35261209408443, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000646334283159, 0.00501512270698302, -0.0157718862589809,
-4.38622292280198, 0.0336108287175509, 0, 0, 0, 0, 0, 0, 0.000637985758628321, 0.00500317467522303, -0.0157904853663509,
-4.41983375151953, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000617414130835201, 0.00488131912259557, -0.0154336678825269,
-4.45344458023708, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000623193437483034, 0.00468067754881618, -0.0148289941333022,
-4.48705540895463, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000597300585209067, 0.00456501378300798, -0.0145170142477132,
-4.52066623767218, 0.0336108287175509, 0, 0, 0, 0, 0, 0, 0.000600515632876235, 0.00449631486751442, -0.0143362607194262,
-4.55427706638973, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000586426011916752, 0.00441283621522315, -0.0141057576910146,
-4.58788789510728, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000563614026592221, 0.00427878434699041, -0.0137268864501221,
-4.62149872382483, 0.0336108287175509, 0, 0, 0, 0, 0, 0, 0.000556792281606696, 0.00410677313018225, -0.0132072844125717,
-4.65510955254238, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000548896497560584, 0.00395929639082955, -0.0127562648045458,
-4.68872038125993, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000528199526802861, 0.00386137109278739, -0.012487654723473,
-4.72233120997748, 0.0336108287175509, 0, 0, 0, 0, 0, 0, 0.000503548565522125, 0.00369349942619724, -0.0119747395719863,
-4.75594203869503, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000499950666371634, 0.0035373425586488, -0.011482574067012,
-4.78955286741258, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000479885599270672, 0.00333462613262273, -0.0108629617747919,
-4.82316369613013, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000455094103808851, 0.0031213823067802, -0.0101924625117216,
-4.85677452484768, 0.0336108287175509, 0, 0, 0, 0, 0, 0, 0.000439944233721587, 0.00287813334603445, -0.00941808065478851,
-4.89038535356523, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000416380779067473, 0.00265320137631905, -0.00870217568115354,
-4.92399618228277, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000392824842514559, 0.00235821312510224, -0.00775137294193924,
-4.95760701100032, 0.0336108287175509, 0, 0, 0, 0, 0, 0, 0.000372698408987385, 0.00203279376760978, -0.00669870155204615,
-4.99121783971787, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000360890127541669, 0.00183261724634729, -0.00607582025639607,
-5.02482866843542, 0.0336108287175492, 0, 0, 0, 0, 0, 0, 0.000472295578714587, 0.00103923232033049, -0.0034467722494315,
-
+Y,blk-1/leftWing_CFx_per_span,blk-1/leftWing_CFz_per_span,blk-1/leftWing_CMy_per_span,blk-1/fuselage_CFx_per_span,blk-1/fuselage_CFz_per_span,blk-1/fuselage_CMy_per_span,blk-1/rightWing_CFx_per_span,blk-1/rightWing_CFz_per_span,blk-1/rightWing_CMy_per_span
+-5.02480911811194000000,0.00047034206908508600,0.00103238078908972000,-0.00342322285934544000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.99119828939439000000,0.00036210197117471200,0.00181757136676592000,-0.00602176907056759000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.95758746067684000000,0.00037649111383760100,0.00202188953519795000,-0.00665895756788854000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.92397663195929000000,0.00039415088146345600,0.00235658489057913000,-0.00774397670429137000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.89036580324174000000,0.00041459282961782900,0.00264489249078894000,-0.00867606521181081000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.85675497452419000000,0.00043861167126274300,0.00292053183000095000,-0.00955796576713591000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.82314414580664000000,0.00045678846648138000,0.00311764674025860000,-0.01017645021086350000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.78953331708909000000,0.00048221721410151300,0.00335921187334712000,-0.01093337820048540000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.75592248837154000000,0.00048686119741628200,0.00353310626586398000,-0.01147382919472310000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.72231165965399000000,0.00051449532020457400,0.00369435655264916000,-0.01197500268440120000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.68870083093644000000,0.00053527454336494200,0.00382555144031057000,-0.01237125073606230000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.65509000221889000000,0.00054085249581352900,0.00404071836259213000,-0.01302871969530670000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.62147917350134000000,0.00054755267245778000,0.00420365386667665000,-0.01350766079008480000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.58786834478379000000,0.00056271448641277000,0.00425533684425497000,-0.01364470894177620000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.55425751606624000000,0.00058162905542093700,0.00431204028336554000,-0.01379548777023830000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.52064668734869000000,0.00060669151819979900,0.00449839605135145000,-0.01433894257651720000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.48703585863114000000,0.00060277479857012100,0.00471597383385303000,-0.01500852860512280000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.45342502991359000000,0.00060741415823587500,0.00478329146348846000,-0.01517727123768390000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.41981420119604000000,0.00061404563952371300,0.00474575078113951000,-0.01499821323883190000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.38620337247849000000,0.00063836342814661100,0.00479763190687746000,-0.01511635642564020000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.35259254376094000000,0.00065875838270311100,0.00500556886621821000,-0.01573922287327390000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.31898171504339000000,0.00065792545370066200,0.00525031420071902000,-0.01647284860471620000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.28537088632584000000,0.00065120714523070200,0.00527579747046633000,-0.01650236300836220000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.25176005760829000000,0.00065941223536416300,0.00521462905099333000,-0.01624615211127120000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.21814922889074000000,0.00069065974833772800,0.00524510955130831000,-0.01630342289351100000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.18453840017319000000,0.00070892732846037200,0.00539123344851971000,-0.01671320197316980000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.15092757145564000000,0.00071026299735275100,0.00559233441011727000,-0.01731327957580630000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.11731674273810000000,0.00070135495010238900,0.00567108631375586000,-0.01748633586247790000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.08370591402054000000,0.00071328341110844300,0.00557875336017110000,-0.01714492169084510000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.05009508530300000000,0.00072418400326291400,0.00560560750742869000,-0.01717697523189990000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-4.01648425658545000000,0.00074415875677277900,0.00569567407142170000,-0.01740843553039330000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.98287342786790000000,0.00075694868954156800,0.00587001502099072000,-0.01791673986997080000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.94926259915035000000,0.00075588804355987500,0.00597457216989749000,-0.01818004023785010000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.91565177043280000000,0.00076633342833469600,0.00594136639966439000,-0.01799525908266190000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.88204094171525000000,0.00076966824487678600,0.00601284546519374000,-0.01814003983525590000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.84843011299770000000,0.00077437340419837100,0.00606979789156753000,-0.01829578940004350000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.81481928428015000000,0.00079605063775158000,0.00610016173445085000,-0.01837222723574670000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.78120845556260000000,0.00081791306359754900,0.00618991763491073000,-0.01855742506420310000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.74759762684505000000,0.00082217134161052900,0.00628302968108633000,-0.01874881557321060000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.71398679812750000000,0.00080764578693701100,0.00632360536570551000,-0.01883346001754000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.68037596940995000000,0.00079725166291459600,0.00631005826265415000,-0.01878080188273670000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.64676514069240000000,0.00083015810232629800,0.00638006413788986000,-0.01889940744717880000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.61315431197485000000,0.00085477570506486900,0.00642716256974645000,-0.01897500569829550000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.57954348325730000000,0.00086646010589205100,0.00649738796388195000,-0.01914963669313940000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.54593265453975000000,0.00085711626175769400,0.00658625552872327000,-0.01936522505127420000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.51232182582220000000,0.00085247664634869100,0.00672074875349641000,-0.01968025784739270000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.47871099710465000000,0.00087320828815864400,0.00661877883934512000,-0.01931379658696120000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.44510016838710000000,0.00088209087479898700,0.00665895477357414000,-0.01939014212152760000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.41148933966955000000,0.00089768490472481900,0.00669691595680408000,-0.01946285827838440000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.37787851095200000000,0.00090484242080699700,0.00669444031170763000,-0.01941707462355690000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.34426768223445000000,0.00090535798139267800,0.00682701945384370000,-0.01973699197605780000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.31065685351690000000,0.00090828114285345100,0.00690959596123263000,-0.01989094951730540000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.27704602479935000000,0.00093496345315741700,0.00678303173377931000,-0.01947184534560420000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.24343519608180000000,0.00094901081860061600,0.00697284398786486000,-0.01998583498635050000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.20982436736425000000,0.00094513674395894300,0.00713526370893061000,-0.02038782286225260000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.17621353864670000000,0.00095375402983800700,0.00696813524685288000,-0.01983716058755490000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.14260270992915000000,0.00095292117550577500,0.00694666712035129000,-0.01975886810671060000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.10899188121160000000,0.00097281022000244000,0.00707596057591230000,-0.02004164184275000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.07538105249405000000,0.00099189669066532800,0.00716333602044201000,-0.02018764811155920000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.04177022377650000000,0.00098577598201403400,0.00726535571526920000,-0.02047478800359000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-3.00815939505896000000,0.00098753640860870600,0.00727578904711210000,-0.02044042316924420000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.97454856634141000000,0.00099807826042200000,0.00712110021801566000,-0.01989592978157310000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.94093773762386000000,0.00101564901717352000,0.00725510941352889000,-0.02025976014556070000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.90732690890631000000,0.00103857508681841000,0.00738166911959137000,-0.02058513958974540000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.87371608018876000000,0.00103399456692514000,0.00726282911727265000,-0.02020340252385060000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.84010525147121000000,0.00103125557097051000,0.00736581703692448000,-0.02038421318283310000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.80649442275366000000,0.00106180188256424000,0.00734875945673505000,-0.02027171027325450000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.77288359403611000000,0.00106979145976391000,0.00733817558994017000,-0.02021026976436730000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.73927276531856000000,0.00106341251216901000,0.00752730251655340000,-0.02072913350427870000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.70566193660101000000,0.00109250338148070000,0.00758432668377364000,-0.02076616745158150000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.67205110788346000000,0.00109333949327935000,0.00748033255766922000,-0.02040183562295500000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.63844027916591000000,0.00110131276862917000,0.00745455851155809000,-0.02031860126434320000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.60482945044836000000,0.00112527347610686000,0.00742950828255858000,-0.02022668920706300000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.57121862173081000000,0.00111921424801135000,0.00764616700805331000,-0.02072583580047370000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.53760779301326000000,0.00113855850645745000,0.00771141152423503000,-0.02082688365891570000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.50399696429571000000,0.00115923400841705000,0.00763250124657736000,-0.02056610734211500000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.47038613557816000000,0.00114971110961475000,0.00752145784467611000,-0.02023953401251340000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.43677530686061000000,0.00115844753654206000,0.00766401975274633000,-0.02051085638460490000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.40316447814306000000,0.00119285039212218000,0.00770235853162850000,-0.02057815217430380000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.36955364942551000000,0.00119044801875096000,0.00769784096052404000,-0.02056261798962790000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.33594282070796000000,0.00120272371277573000,0.00779091756633651000,-0.02071396666966940000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.30233199199041000000,0.00122246916219800000,0.00778278310910058000,-0.02059645699200430000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.26872116327286000000,0.00123232778897561000,0.00769450751797757000,-0.02035667587894520000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.23511033455531000000,0.00122982267047178000,0.00765864159658575000,-0.02022738466185410000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.20149950583776000000,0.00123741196744043000,0.00781125191492394000,-0.02055514214503670000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.16788867712021000000,0.00125190644686348000,0.00780680988740199000,-0.02047337528500570000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.13427784840266000000,0.00126375908398306000,0.00781933643051637000,-0.02047262838466250000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.10066701968511000000,0.00128884559558024000,0.00774845043754225000,-0.02025218963283380000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.06705619096756000000,0.00129868404187919000,0.00770613854815638000,-0.02008065062619360000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-2.03344536225001000000,0.00130858184307318000,0.00782481984628942000,-0.02034635829794110000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.99983453353246000000,0.00133794879094756000,0.00795541567209259000,-0.02063601113169860000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.96622370481491000000,0.00132860675623339000,0.00782236483374132000,-0.02021217170447330000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.93261287609736000000,0.00132630083908833000,0.00779785337786681000,-0.02011918234409130000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.89900204737981000000,0.00137421435218484000,0.00779611113773535000,-0.02009903321797820000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.86539121866227000000,0.00138723993619545000,0.00785782587072532000,-0.02017221908089580000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.83178038994472000000,0.00138321590134603000,0.00797230135846759000,-0.02039965657394870000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.79816956122717000000,0.00139241193194970000,0.00789813408290209000,-0.02014937428958320000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.76455873250962000000,0.00140005662757185000,0.00779194470231723000,-0.01990457371240040000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.73094790379207000000,0.00143539942695382000,0.00785925641054603000,-0.01999860239356060000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.69733707507452000000,0.00144170880708726000,0.00789419336667183000,-0.01998700982036340000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.66372624635697000000,0.00144764287991371000,0.00790255600308674000,-0.01998264657665430000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.63011541763942000000,0.00145614993003944000,0.00787968494840595000,-0.01994900208415110000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.59650458892187000000,0.00146632564901676000,0.00781445057818542000,-0.01970525894497100000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.56289376020432000000,0.00150256516954160000,0.00788479723666074000,-0.01980132955713750000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.52928293148677000000,0.00150437164778609000,0.00788498467488710000,-0.01974591475788640000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.49567210276922000000,0.00151981777970998000,0.00782044786084702000,-0.01961334590272640000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.46206127405167000000,0.00153235370142524000,0.00775175459542972000,-0.01945905177959270000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.42845044533412000000,0.00153944952557890000,0.00780192048947760000,-0.01944820540706090000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.39483961661657000000,0.00155615145631580000,0.00788588886749136000,-0.01960462018892570000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.36122878789902000000,0.00157830493501260000,0.00780974040213685000,-0.01941516919330480000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.32761795918147000000,0.00159555806297675000,0.00775768026346238000,-0.01926908767230520000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.29400713046392000000,0.00159102129817719000,0.00776965519256371000,-0.01920176367949290000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.26039630174637000000,0.00160955752388377000,0.00778771274845467000,-0.01920821357165040000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.22678547302882000000,0.00162045973487659000,0.00775459020583298000,-0.01915093426453770000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.19317464431127000000,0.00163691218818199000,0.00771595275404383000,-0.01907307859639910000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.15956381559372000000,0.00164831212067262000,0.00759349148024402000,-0.01871087039757190000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.12595298687617000000,0.00166692051872794000,0.00766460952556926000,-0.01878257561910750000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.09234215815862000000,0.00168353629213769000,0.00761499398469513000,-0.01867292526296710000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.05873132944107000000,0.00168675976997690000,0.00763581103023003000,-0.01868284395380570000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-1.02512050072352000000,0.00170157959051467000,0.00764408641278503000,-0.01867310761200150000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.99150967200597300000,0.00173830688951988000,0.00749127301477849000,-0.01833301310668130000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.95789884328842300000,0.00173532899257238000,0.00733799511155013000,-0.01796843301585800000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.92428801457087400000,0.00173801003312147000,0.00744800017566516000,-0.01813786226806740000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.89067718585332400000,0.00175015108657065000,0.00752168284392443000,-0.01826385898467180000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.85706635713577400000,0.00176397133792544000,0.00736837608198434000,-0.01794344639522510000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.82345552841822400000,0.00179068613424831000,0.00725750363854718000,-0.01770955829628370000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.78984469970067500000,0.00180343927001596000,0.00724320755156654000,-0.01763793175058280000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.75623387098312500000,0.00179307792973748000,0.00726034016911441000,-0.01757673585890000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.72262304226557500000,0.00181853467582665000,0.00720732721960750000,-0.01750357825836830000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.68901221354802500000,0.00181485131493534000,0.00706043781231928000,-0.01715959915782810000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.65540138483047600000,0.00182612941102705000,0.00695237605950437000,-0.01692494882510100000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.62179055611292600000,0.00186181022139975000,0.00700901765118897000,-0.01705110819685990000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.58817972739537700000,0.00189219709352808000,0.00703653121385452000,-0.01707368897285610000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.55456889867782700000,0.00192816156367794000,0.00705332004140741000,-0.01698187387374710000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.52095806996027700000,0.00199291431521547000,0.00708362328665730000,-0.01693860856134130000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.48734724124272700000,0.00198936049994366000,0.00692912012051487000,-0.01675299270458540000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.45373641252517800000,0.00133909886998168000,0.00853123575077830000,-0.01887971087075900000,0.00099405938899702900,-0.00156582507391184000,0.00217264156016244000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.42012558380762800000,0.00109688839889628000,0.00937705002837353000,-0.02007771359127910000,0.00225728591051082000,-0.00206038772004637000,0.00302103756932170000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.38651475509007800000,0.00087020383206157200,0.00831167626315296000,-0.01840405749027970000,0.00357243027893747000,-0.00092482522131348900,0.00138737591283402000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.35290392637252800000,0.00014564512173509200,0.00237028281712212000,-0.00530980523191098000,0.00657591401614288000,0.00596432663647871000,-0.01408341027367490000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.31929309765497900000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00609186538634942000,0.00766361018796394000,-0.01795679358130040000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.28568226893742900000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00553086721357205000,0.00730832017413336000,-0.01741598697102060000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.25207144021988000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00505976086611972000,0.00731081883784560000,-0.01727661147505930000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.21846061150233000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00465378728122627000,0.00690634031000821000,-0.01646497580334450000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.18484978278478000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00439602416682022000,0.00701430627933367000,-0.01681124161883750000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.15123895406723000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00421131184844060000,0.00675045971654009000,-0.01627330317562700000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.11762812534968100000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00420309692930225000,0.00676331910239671000,-0.01626654398321690000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.08401729663213110000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00445754758930279000,0.00683827219911990000,-0.01633992513113390000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.05040646791458100000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00538764144198720000,0.00666533085251443000,-0.01603318644008310000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+-0.01679563919703140000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00735624820146298000,0.00674070577967040000,-0.01615159465150560000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+0.01681518952051820000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00736559426919886000,0.00671489568372628000,-0.01615762729817090000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+0.05042601823806780000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00536893279283081000,0.00666186986238470000,-0.01601259305021190000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+0.08403684695561740000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00445126089931289000,0.00680570172415461000,-0.01632021993094630000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+0.11764767567316700000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00420007178787320000,0.00676934738796828000,-0.01628660727353080000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+0.15125850439071700000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00419324414368048000,0.00679724469199551000,-0.01620872979719450000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+0.18486933310826700000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00441073779476435000,0.00708375503347185000,-0.01690531755921890000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+0.21848016182581600000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00465959016962243000,0.00677396812305508000,-0.01629115197916660000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+0.25209099054336600000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00507062929643877000,0.00731757824487935000,-0.01723200591562360000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+0.28570181926091600000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00554406479628231000,0.00713759748122594000,-0.01707464702015410000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+0.31931264797846600000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00607644567741382000,0.00779816822526878000,-0.01813290298012680000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000
+0.35292347669601500000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00658258057901175000,0.00577781433454318000,-0.01378464795316570000,0.00014697976803677400,0.00237678859810206000,-0.00532307297939396000
+0.38653430541356500000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00354220589740535000,-0.00079052781833322700,0.00114192131560859000,0.00086441326420984600,0.00825218982701490000,-0.01825021331862080000
+0.42014513413111400000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00227115036478823000,-0.00208835592089667000,0.00307438800950459000,0.00109343881882253000,0.00935602035565083000,-0.02001577414027740000
+0.45375596284866400000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00101093671190196000,-0.00156242925680780000,0.00217303408846517000,0.00134915800521793000,0.00853134441804222000,-0.01884978030871690000
+0.48736679156621400000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00199296466135107000,0.00675254899530676000,-0.01636919441753570000
+0.52097762028376400000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00200432124703397000,0.00699443206858486000,-0.01676172140528060000
+0.55458844900131300000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00193895358143152000,0.00709136752275001000,-0.01703064915055630000
+0.58819927771886300000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00189761961696624000,0.00699930446565475000,-0.01694948116309100000
+0.62181010643641300000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00185857584255041000,0.00696111694783956000,-0.01691643726682220000
+0.65542093515396300000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00183400553433561000,0.00703373030573242000,-0.01708413391273390000
+0.68903176387151200000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00183212317556560000,0.00707209074026941000,-0.01720441156514560000
+0.72264259258906200000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00182069957957905000,0.00717799588263588000,-0.01744063297898300000
+0.75625342130661100000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00180965985184215000,0.00722434797781003000,-0.01753731073187010000
+0.78986425002416100000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00178846582444991000,0.00722885234205631000,-0.01758663456758760000
+0.82347507874171100000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00177215502338515000,0.00730804022248511000,-0.01778481977313830000
+0.85708590745926100000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00177411093483938000,0.00730371258195732000,-0.01777740068534960000
+0.89069673617681000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00176380111720723000,0.00747243476874846000,-0.01816460130010000000
+0.92430756489436000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00174445881399173000,0.00749764704395638000,-0.01828520864980430000
+0.95791839361191000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00172970394108330000,0.00746076656929297000,-0.01824320300154760000
+0.99152922232946000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00171419794539665000,0.00753301379878302000,-0.01841485748841430000
+1.02514005104701000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00171710285625330000,0.00758486997756415000,-0.01855465122755680000
+1.05875087976456000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00170633450129727000,0.00751021685163381000,-0.01843397135796450000
+1.09236170848211000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00167357093351958000,0.00761126706614621000,-0.01867496484894430000
+1.12597253719966000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00166678001788129000,0.00763374984857316000,-0.01878808177206130000
+1.15958336591721000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00164833920287982000,0.00772235687851386000,-0.01896321614541640000
+1.19319419463476000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00164422534206491000,0.00771479553940106000,-0.01899696633061150000
+1.22680502335231000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00163273526793667000,0.00773238211626325000,-0.01908476233294280000
+1.26041585206986000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00162175730774744000,0.00774184369330461000,-0.01913193205112650000
+1.29402668078741000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00160325769583000000,0.00776857214777246000,-0.01926234421286810000
+1.32763750950496000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00157643328049390000,0.00776270134357302000,-0.01927718509561670000
+1.36124833822251000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00157425727010903000,0.00777545960607258000,-0.01930321394988600000
+1.39485916694006000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00155737071172632000,0.00783358218786056000,-0.01951019542322770000
+1.42846999565761000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00154513351409666000,0.00783150824955357000,-0.01952145858982790000
+1.46208082437516000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00152720382828700000,0.00779237851516276000,-0.01948531525711770000
+1.49569165309271000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00150529861124180000,0.00776846121968105000,-0.01946348208685400000
+1.52930248181025000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00151043341861451000,0.00789337336906524000,-0.01984447138389090000
+1.56291331052780000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00151183788390668000,0.00785586680553428000,-0.01976011090643520000
+1.59652413924535000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00148039266638568000,0.00786298294667155000,-0.01981628186667070000
+1.63013496796290000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00144588378269087000,0.00786716175651594000,-0.01985898445728880000
+1.66374579668045000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00142779951652779000,0.00785606998006967000,-0.01987907283083130000
+1.69735662539800000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00144177433046979000,0.00794982448019128000,-0.02013405795011630000
+1.73096745411555000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00143625384017713000,0.00797340360714148000,-0.02026731299629290000
+1.76457828283310000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00141391958099660000,0.00776076525724547000,-0.01983589402513570000
+1.79818911155065000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00138049676000345000,0.00777485988215951000,-0.01990016281923840000
+1.83179994026820000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00137098152394187000,0.00782921058601074000,-0.02004049822920420000
+1.86541076898575000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00138348238162994000,0.00794890361180001000,-0.02033855918358330000
+1.89902159770330000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00138060187199278000,0.00796158444794812000,-0.02046671718826890000
+1.93263242642085000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00137240247529101000,0.00782660963167805000,-0.02025405621415010000
+1.96624325513840000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00133218263029819000,0.00772229466604732000,-0.02001333549610700000
+1.99985408385595000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00130271933573658000,0.00783314291578209000,-0.02029931890316660000
+2.03346491257350000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00130338307463390000,0.00781963431960125000,-0.02030565556444860000
+2.06707574129105000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00131457164387243000,0.00784971845931837000,-0.02047872110140010000
+2.10068657000860000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00129875950788775000,0.00782825861034154000,-0.02047606053624720000
+2.13429739872615000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00126976075075216000,0.00779101820331443000,-0.02042852152753070000
+2.16790822744370000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00125611838874534000,0.00776996097994982000,-0.02040396536706780000
+2.20151905616125000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00124734279425741000,0.00772432216131663000,-0.02031879400977230000
+2.23512988487880000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00122640365663200000,0.00774053552281337000,-0.02040327354650570000
+2.26874071359635000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00122794609587348000,0.00780790495670122000,-0.02065735373945140000
+2.30235154231390000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00122766922606352000,0.00781366451226181000,-0.02076242646144570000
+2.33596237103145000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00120130291037364000,0.00770903372450750000,-0.02051981431769160000
+2.36957319974900000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00117165835371223000,0.00766201056067202000,-0.02040355094365550000
+2.40318402846655000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00118007690958911000,0.00756840656150893000,-0.02022850326709910000
+2.43679485718410000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00117208814309608000,0.00763418502046047000,-0.02048413789077320000
+2.47040568590165000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00116905774039806000,0.00765512130439508000,-0.02057449192483400000
+2.50401651461920000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00114885383649190000,0.00766408421770890000,-0.02067430548738470000
+2.53762734333675000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00113665465106545000,0.00766735753148298000,-0.02069726163257490000
+2.57123817205430000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00112312464198117000,0.00757841949775475000,-0.02051957464135040000
+2.60484900077185000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00111076168345014000,0.00750755202617586000,-0.02038506565975080000
+2.63845982948940000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00110509596312147000,0.00758736776004868000,-0.02068811594321840000
+2.67207065820694000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00110125893222163000,0.00744064140191101000,-0.02034981870273320000
+2.70568148692449000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00107384293779697000,0.00739998876072871000,-0.02027985334901660000
+2.73929231564204000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00107739104988549000,0.00746674062308083000,-0.02049865661603640000
+2.77290314435959000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00106931045831918000,0.00739935684404182000,-0.02037604278505390000
+2.80651397307714000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00106825651565179000,0.00740614841865683000,-0.02045615575254410000
+2.84012480179469000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00104721868161754000,0.00743889598874306000,-0.02060003113586960000
+2.87373563051224000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00103894807896862000,0.00724846711029415000,-0.02015155126966620000
+2.90734645922979000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00101893703689658000,0.00725213431256654000,-0.02017757159854030000
+2.94095728794734000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00101412980038703000,0.00737500971589565000,-0.02055921114240790000
+2.97456811666489000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00101595923706723000,0.00721829340521934000,-0.02021927448859570000
+3.00817894538244000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00099961679001309300,0.00717525960911597000,-0.02016872909672900000
+3.04178977409999000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00098801650264084600,0.00718149573442461000,-0.02022843821350020000
+3.07540060281754000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00097874323258004400,0.00701636858484985000,-0.01981290338288830000
+3.10901143153509000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00097124122812418200,0.00711555002625144000,-0.02013461431821360000
+3.14262226025264000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00098098985666595700,0.00712259100955782000,-0.02024344308288450000
+3.17623308897019000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00095550130772011600,0.00691456941105626000,-0.01971469090556060000
+3.20984391768774000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00092824633749782200,0.00701886686369715000,-0.02006831707146790000
+3.24345474640529000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00092547831955115100,0.00692008338694790000,-0.01981750569535000000
+3.27706557512284000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00092664425560362800,0.00683088110167545000,-0.01961144950744490000
+3.31067640384039000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00092413187840812200,0.00696093297578957000,-0.02004759563427510000
+3.34428723255794000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00092003289157176100,0.00682804807610617000,-0.01973812948282380000
+3.37789806127549000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00089654597875992000,0.00666839780413866000,-0.01932472603786860000
+3.41150888999304000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00089219628370836600,0.00674857677816546000,-0.01959079866961270000
+3.44511971871059000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00088908185898664100,0.00664931627517708000,-0.01935618446447200000
+3.47873054742814000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00088452000579617500,0.00665569881591357000,-0.01943882110646220000
+3.51234137614569000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00086945192142279400,0.00669631997745908000,-0.01962669341345370000
+3.54595220486324000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00085485767153240900,0.00648968431871053000,-0.01907565485077720000
+3.57956303358079000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00084879266728247700,0.00633768383281939000,-0.01868082833929970000
+3.61317386229834000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00083569582702730500,0.00636922496456482000,-0.01878552551705220000
+3.64678469101589000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00084601071831607500,0.00637569686779853000,-0.01890408123650890000
+3.68039551973344000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00082893448446961800,0.00647338403885935000,-0.01926465193970860000
+3.71400634845099000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00081689943368125200,0.00630819315157258000,-0.01882179751315240000
+3.74761717716854000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00081573945153688900,0.00608384978247865000,-0.01815295925236460000
+3.78122800588608000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00079181287061361100,0.00606811231883676000,-0.01816055054495490000
+3.81483883460363000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00078329507429140200,0.00620936747727471000,-0.01865696023281320000
+3.84844966332118000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00078383965397809600,0.00620640730470964000,-0.01872860644633010000
+3.88206049203873000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00077129675271282700,0.00603752650003367000,-0.01824748299157200000
+3.91567132075628000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00076939736771843900,0.00584327139072089000,-0.01770023285751410000
+3.94928214947383000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00074349422805079200,0.00579402899096100000,-0.01758602713360080000
+3.98289297819138000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00074677157514738000,0.00584187049813201000,-0.01780395316160030000
+4.01650380690893000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00074916354961267200,0.00588627244111973000,-0.01801344304387800000
+4.05011463562648000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00073087700974504500,0.00573630250009650000,-0.01759205633659220000
+4.08372546434403000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00072587739443037000,0.00555343312614800000,-0.01706486828939530000
+4.11733629306158000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00071030998096655600,0.00554579289417955000,-0.01708298077485590000
+4.15094712177913000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00069891654584012100,0.00547419877928839000,-0.01692374930330870000
+4.18455795049668000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00070958109012289300,0.00546998703505875000,-0.01696354055508250000
+4.21816877921423000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00068043106199308100,0.00536648860695189000,-0.01668190481466160000
+4.25177960793178000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00067607578434899000,0.00521768182116309000,-0.01629955218957300000
+4.28539043664933000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00067421161111079700,0.00512385956397980000,-0.01602532713293500000
+4.31900126536688000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00065294571280469000,0.00500326319828527000,-0.01565862249542810000
+4.35261209408443000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00064633428315900000,0.00501512270698302000,-0.01577188625898090000
+4.38622292280198000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00063798575862832100,0.00500317467522303000,-0.01579048536635090000
+4.41983375151953000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00061741413083520100,0.00488131912259557000,-0.01543366788252690000
+4.45344458023708000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00062319343748303400,0.00468067754881618000,-0.01482899413330220000
+4.48705540895463000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00059730058520906700,0.00456501378300798000,-0.01451701424771320000
+4.52066623767218000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00060051563287623500,0.00449631486751442000,-0.01433626071942620000
+4.55427706638973000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00058642601191675200,0.00441283621522315000,-0.01410575769101460000
+4.58788789510728000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00056361402659222100,0.00427878434699041000,-0.01372688645012210000
+4.62149872382483000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00055679228160669600,0.00410677313018225000,-0.01320728441257170000
+4.65510955254238000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00054889649756058400,0.00395929639082955000,-0.01275626480454580000
+4.68872038125993000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00052819952680286100,0.00386137109278739000,-0.01248765472347300000
+4.72233120997748000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00050354856552212500,0.00369349942619724000,-0.01197473957198630000
+4.75594203869503000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00049995066637163400,0.00353734255864880000,-0.01148257406701200000
+4.78955286741258000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00047988559927067200,0.00333462613262273000,-0.01086296177479190000
+4.82316369613013000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00045509410380885100,0.00312138230678020000,-0.01019246251172160000
+4.85677452484768000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00043994423372158700,0.00287813334603445000,-0.00941808065478851000
+4.89038535356523000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00041638077906747300,0.00265320137631905000,-0.00870217568115354000
+4.92399618228277000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00039282484251455900,0.00235821312510224000,-0.00775137294193924000
+4.95760701100032000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00037269840898738500,0.00203279376760978000,-0.00669870155204615000
+4.99121783971787000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00036089012754166900,0.00183261724634729000,-0.00607582025639607000
+5.02482866843542000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00000000000000000000,0.00047229557871458700,0.00103923232033049000,-0.00344677224943150000
\ No newline at end of file
diff --git a/tests/data/case-84d4604e-f3cd-4c6b-8517-92a80a3346d3/simulation.json b/tests/data/case-84d4604e-f3cd-4c6b-8517-92a80a3346d3/simulation.json
index 72e81e07b..b59217a47 100644
--- a/tests/data/case-84d4604e-f3cd-4c6b-8517-92a80a3346d3/simulation.json
+++ b/tests/data/case-84d4604e-f3cd-4c6b-8517-92a80a3346d3/simulation.json
@@ -1 +1 @@
-{"version":"24.11.0","unit_system":{"name":"SI"},"meshing":{"refinement_factor":1.0,"gap_treatment_strength":0.0,"defaults":{"surface_edge_growth_rate":1.15,"boundary_layer_growth_rate":1.15,"boundary_layer_first_layer_thickness":{"value":1e-6,"units":"m"},"surface_max_edge_length":{"value":0.03,"units":"m"},"curvature_resolution_angle":{"value":8.0,"units":"degree"}},"refinements":[{"name":"leadingEdge","refinement_type":"SurfaceEdgeRefinement","entities":{"stored_entities":[{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"leadingEdge","private_attribute_tag_key":"edgeName","private_attribute_sub_components":["body0001_edge0003"]}]},"method":{"type":"angle","value":{"value":1.0,"units":"degree"}}},{"name":"trailingEdge","refinement_type":"SurfaceEdgeRefinement","entities":{"stored_entities":[{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"trailingEdge","private_attribute_tag_key":"edgeName","private_attribute_sub_components":["body0001_edge0001","body0001_edge0006"]}]},"method":{"type":"height","value":{"value":0.001,"units":"m"}}}],"volume_zones":[{"spacing_axial":{"value":0.04,"units":"m"},"spacing_radial":{"value":0.04,"units":"m"},"spacing_circumferential":{"value":0.04,"units":"m"},"type":"RotationCylinder","name":null,"entities":{"stored_entities":[{"private_attribute_registry_bucket_name":"VolumetricEntityType","private_attribute_entity_type_name":"Cylinder","private_attribute_id":"017e631a-34ae-45f8-96c3-2bb0fa5cf2f2","name":"cylinder","private_attribute_zone_boundary_names":{"items":[]},"private_attribute_full_name":null,"axis":[0.0,1.0,0.0],"center":{"value":[0.0,0.0,0.0],"units":"m"},"height":{"value":2.5,"units":"m"},"inner_radius":{"value":0.0,"units":"m"},"outer_radius":{"value":1.0,"units":"m"}}]},"enclosed_entities":{"stored_entities":[{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"Surface","private_attribute_id":null,"name":"wing","private_attribute_full_name":null,"private_attribute_is_interface":null,"private_attribute_tag_key":"faceName","private_attribute_sub_components":["body0001_face0001","body0001_face0002","body0001_face0003","body0001_face0004","body0001_face0005"]}]}},{"type":"AutomatedFarfield","name":"farfield","method":"auto"}]},"reference_geometry":{"moment_center":{"value":[0.0,0.0,0.0],"units":"m"},"moment_length":{"value":[1.0,1.0,1.0],"units":"m"},"area":{"value":2.0,"units":"m**2"}},"operating_condition":{"type_name":"AerospaceCondition","private_attribute_constructor":"default","private_attribute_input_cache":{"mach":null,"alpha":null,"beta":null,"thermal_state":null,"reference_mach":null},"alpha":{"value":0.0,"units":"degree"},"beta":{"value":0.0,"units":"degree"},"velocity_magnitude":{"value":50.0,"units":"m/s"},"thermal_state":{"type_name":"ThermalState","private_attribute_constructor":"default","private_attribute_input_cache":{"altitude":null,"temperature_offset":null},"temperature":{"value":288.15,"units":"K"},"density":{"value":1.225,"units":"kg/m**3"},"material":{"type":"air","name":"air","dynamic_viscosity":{"reference_viscosity":{"value":0.00001716,"units":"Pa*s"},"reference_temperature":{"value":273.15,"units":"K"},"effective_temperature":{"value":110.4,"units":"K"}}}},"reference_velocity_magnitude":null},"models":[{"name":null,"type":"Rotation","entities":{"stored_entities":[{"private_attribute_registry_bucket_name":"VolumetricEntityType","private_attribute_entity_type_name":"Cylinder","private_attribute_id":"017e631a-34ae-45f8-96c3-2bb0fa5cf2f2","name":"cylinder","private_attribute_zone_boundary_names":{"items":[]},"private_attribute_full_name":null,"axis":[0.0,1.0,0.0],"center":{"value":[0.0,0.0,0.0],"units":"m"},"height":{"value":2.5,"units":"m"},"inner_radius":{"value":0.0,"units":"m"},"outer_radius":{"value":1.0,"units":"m"}}]},"spec":{"value":"0.0349066*sin(0.05877271*t)","type_name":"AngleExpression"},"parent_volume":null},{"type":"Freestream","entities":{"stored_entities":[{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"GhostSurface","private_attribute_id":null,"name":"farfield","private_attribute_full_name":"__farfield_zone_name_not_properly_set_yet/farfield"}]},"turbulence_quantities":null,"name":"Freestream","velocity":null},{"type":"Wall","entities":{"stored_entities":[{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"Surface","private_attribute_id":null,"name":"wing","private_attribute_full_name":null,"private_attribute_is_interface":null,"private_attribute_tag_key":"faceName","private_attribute_sub_components":["body0001_face0001","body0001_face0002","body0001_face0003","body0001_face0004","body0001_face0005"]}]},"name":"NoSlipWall","use_wall_function":false,"velocity":null,"heat_spec":{"value":{"value":0.0,"units":"W/m**2"},"type_name":"HeatFlux"}},{"material":{"type":"air","name":"air","dynamic_viscosity":{"reference_viscosity":{"value":0.00001716,"units":"Pa*s"},"reference_temperature":{"value":273.15,"units":"K"},"effective_temperature":{"value":110.4,"units":"K"}}},"initial_condition":{"type_name":"NavierStokesInitialCondition","constants":null,"rho":"rho","u":"u","v":"v","w":"w","p":"p"},"type":"Fluid","navier_stokes_solver":{"absolute_tolerance":1e-9,"relative_tolerance":0.0,"order_of_accuracy":2,"equation_evaluation_frequency":1,"linear_solver":{"max_iterations":35,"absolute_tolerance":null,"relative_tolerance":null},"CFL_multiplier":1.0,"kappa_MUSCL":-1.0,"numerical_dissipation_factor":1.0,"limit_velocity":false,"limit_pressure_density":false,"type_name":"Compressible","low_mach_preconditioner":false,"low_mach_preconditioner_threshold":null,"update_jacobian_frequency":4,"max_force_jac_update_physical_steps":0},"turbulence_model_solver":{"absolute_tolerance":1e-8,"relative_tolerance":0.0,"order_of_accuracy":2,"equation_evaluation_frequency":4,"linear_solver":{"max_iterations":25,"absolute_tolerance":null,"relative_tolerance":null},"CFL_multiplier":2.0,"type_name":"SpalartAllmaras","reconstruction_gradient_limiter":0.5,"quadratic_constitutive_relation":false,"modeling_constants":{"type_name":"SpalartAllmarasConsts","C_DES":0.72,"C_d":8.0,"C_cb1":0.1355,"C_cb2":0.622,"C_sigma":0.6666666666666666,"C_v1":7.1,"C_vonKarman":0.41,"C_w2":0.3,"C_t3":1.2,"C_t4":0.5,"C_min_rd":10.0},"update_jacobian_frequency":4,"max_force_jac_update_physical_steps":0,"rotation_correction":false},"transition_model_solver":{"type_name":"None"}}],"time_stepping":{"order_of_accuracy":2,"type_name":"Unsteady","max_pseudo_steps":80,"steps":400,"step_size":{"value":0.0031415926535897933,"units":"s"},"CFL":{"type":"ramp","initial":1.0,"final":100000000.0,"ramp_steps":20}},"user_defined_dynamics":null,"user_defined_fields":[],"outputs":[{"frequency":-1,"frequency_offset":0,"output_format":"paraview","name":"VolumeOutput","output_fields":{"items":["Mach"]},"output_type":"VolumeOutput"},{"frequency":-1,"frequency_offset":0,"output_format":"paraview","name":"SurfaceOutput","entities":{"stored_entities":[{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"Surface","private_attribute_id":null,"name":"wing","private_attribute_full_name":null,"private_attribute_is_interface":null,"private_attribute_tag_key":"faceName","private_attribute_sub_components":["body0001_face0001","body0001_face0002","body0001_face0003","body0001_face0004","body0001_face0005"]}]},"write_single_file":false,"output_fields":{"items":["Cp","CfVec"]},"output_type":"SurfaceOutput"}],"private_attribute_asset_cache":{"project_length_unit":{"value":1.0,"units":"m"},"project_entity_info":{"draft_entities":[{"private_attribute_registry_bucket_name":"VolumetricEntityType","private_attribute_entity_type_name":"Cylinder","private_attribute_id":"017e631a-34ae-45f8-96c3-2bb0fa5cf2f2","name":"cylinder","private_attribute_zone_boundary_names":{"items":[]},"private_attribute_full_name":null,"axis":[0.0,1.0,0.0],"center":{"value":[0.0,0.0,0.0],"units":"m"},"height":{"value":2.5,"units":"m"},"inner_radius":{"value":0.0,"units":"m"},"outer_radius":{"value":1.0,"units":"m"}}],"ghost_entities":[{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"GhostSurface","private_attribute_id":null,"name":"farfield","private_attribute_full_name":null,"type_name":"GhostSphere","center":[0.2500000000000003,0.0,1.2478015079531168e-9],"max_radius":106.00174010911132},{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"GhostCircularPlane","private_attribute_id":null,"name":"symmetric-1","private_attribute_full_name":null,"center":[0.2500000000000003,-1.0600174010911132,1.2478015079531168e-9],"max_radius":2.1200348021822264,"normal_axis":[0,1,0]},{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"GhostCircularPlane","private_attribute_id":null,"name":"symmetric-2","private_attribute_full_name":null,"center":[0.2500000000000003,1.0600174010911132,1.2478015079531168e-9],"max_radius":2.1200348021822264,"normal_axis":[0,1,0]}],"type_name":"GeometryEntityInfo","face_ids":["body0001_face0001","body0001_face0002","body0001_face0003","body0001_face0004","body0001_face0005"],"face_attribute_names":["faceName","groupName","faceId"],"grouped_faces":[[{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"Surface","private_attribute_id":null,"name":"wing","private_attribute_full_name":null,"private_attribute_is_interface":null,"private_attribute_tag_key":"faceName","private_attribute_sub_components":["body0001_face0001","body0001_face0002","body0001_face0003","body0001_face0004","body0001_face0005"]}],[{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"Surface","private_attribute_id":null,"name":"wing","private_attribute_full_name":null,"private_attribute_is_interface":null,"private_attribute_tag_key":"groupName","private_attribute_sub_components":["body0001_face0001","body0001_face0002","body0001_face0003","body0001_face0004","body0001_face0005"]}],[{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"Surface","private_attribute_id":null,"name":"body0001_face0001","private_attribute_full_name":null,"private_attribute_is_interface":null,"private_attribute_tag_key":"faceId","private_attribute_sub_components":["body0001_face0001"]},{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"Surface","private_attribute_id":null,"name":"body0001_face0002","private_attribute_full_name":null,"private_attribute_is_interface":null,"private_attribute_tag_key":"faceId","private_attribute_sub_components":["body0001_face0002"]},{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"Surface","private_attribute_id":null,"name":"body0001_face0003","private_attribute_full_name":null,"private_attribute_is_interface":null,"private_attribute_tag_key":"faceId","private_attribute_sub_components":["body0001_face0003"]},{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"Surface","private_attribute_id":null,"name":"body0001_face0004","private_attribute_full_name":null,"private_attribute_is_interface":null,"private_attribute_tag_key":"faceId","private_attribute_sub_components":["body0001_face0004"]},{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"Surface","private_attribute_id":null,"name":"body0001_face0005","private_attribute_full_name":null,"private_attribute_is_interface":null,"private_attribute_tag_key":"faceId","private_attribute_sub_components":["body0001_face0005"]}]],"edge_ids":["body0001_edge0001","body0001_edge0002","body0001_edge0003","body0001_edge0004","body0001_edge0005","body0001_edge0006","body0001_edge0007","body0001_edge0008","body0001_edge0010","body0001_edge0011","body0001_edge0013"],"edge_attribute_names":["edgeName","edgeId"],"grouped_edges":[[{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"trailingEdge","private_attribute_tag_key":"edgeName","private_attribute_sub_components":["body0001_edge0001","body0001_edge0006"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"leadingEdge","private_attribute_tag_key":"edgeName","private_attribute_sub_components":["body0001_edge0003"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0002","private_attribute_tag_key":"__standalone__","private_attribute_sub_components":["body0001_edge0002"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0004","private_attribute_tag_key":"__standalone__","private_attribute_sub_components":["body0001_edge0004"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0005","private_attribute_tag_key":"__standalone__","private_attribute_sub_components":["body0001_edge0005"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0007","private_attribute_tag_key":"__standalone__","private_attribute_sub_components":["body0001_edge0007"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0008","private_attribute_tag_key":"__standalone__","private_attribute_sub_components":["body0001_edge0008"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0010","private_attribute_tag_key":"__standalone__","private_attribute_sub_components":["body0001_edge0010"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0011","private_attribute_tag_key":"__standalone__","private_attribute_sub_components":["body0001_edge0011"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0013","private_attribute_tag_key":"__standalone__","private_attribute_sub_components":["body0001_edge0013"]}],[{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0001","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0001"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0002","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0002"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0003","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0003"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0004","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0004"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0005","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0005"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0006","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0006"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0007","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0007"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0008","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0008"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0010","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0010"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0011","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0011"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0013","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0013"]}]],"face_group_tag":"faceName","edge_group_tag":"edgeName"}}}
\ No newline at end of file
+{"version":"24.11.0","unit_system":{"name":"SI"},"meshing":{"refinement_factor":1.0,"gap_treatment_strength":0.0,"defaults":{"surface_edge_growth_rate":1.15,"boundary_layer_growth_rate":1.15,"boundary_layer_first_layer_thickness":{"value":1e-6,"units":"m"},"surface_max_edge_length":{"value":0.03,"units":"m"},"curvature_resolution_angle":{"value":8.0,"units":"degree"}},"refinements":[{"name":"leadingEdge","refinement_type":"SurfaceEdgeRefinement","entities":{"stored_entities":[{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"leadingEdge","private_attribute_tag_key":"edgeName","private_attribute_sub_components":["body0001_edge0003"]}]},"method":{"type":"angle","value":{"value":1.0,"units":"degree"}}},{"name":"trailingEdge","refinement_type":"SurfaceEdgeRefinement","entities":{"stored_entities":[{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"trailingEdge","private_attribute_tag_key":"edgeName","private_attribute_sub_components":["body0001_edge0001","body0001_edge0006"]}]},"method":{"type":"height","value":{"value":0.001,"units":"m"}}}],"volume_zones":[{"spacing_axial":{"value":0.04,"units":"m"},"spacing_radial":{"value":0.04,"units":"m"},"spacing_circumferential":{"value":0.04,"units":"m"},"type":"RotationVolume","name":null,"entities":{"stored_entities":[{"private_attribute_registry_bucket_name":"VolumetricEntityType","private_attribute_entity_type_name":"Cylinder","private_attribute_id":"017e631a-34ae-45f8-96c3-2bb0fa5cf2f2","name":"cylinder","private_attribute_zone_boundary_names":{"items":[]},"private_attribute_full_name":null,"axis":[0.0,1.0,0.0],"center":{"value":[0.0,0.0,0.0],"units":"m"},"height":{"value":2.5,"units":"m"},"inner_radius":{"value":0.0,"units":"m"},"outer_radius":{"value":1.0,"units":"m"}}]},"enclosed_entities":{"stored_entities":[{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"Surface","private_attribute_id":null,"name":"wing","private_attribute_full_name":null,"private_attribute_is_interface":null,"private_attribute_tag_key":"faceName","private_attribute_sub_components":["body0001_face0001","body0001_face0002","body0001_face0003","body0001_face0004","body0001_face0005"]}]}},{"type":"AutomatedFarfield","name":"farfield","method":"auto"}]},"reference_geometry":{"moment_center":{"value":[0.0,0.0,0.0],"units":"m"},"moment_length":{"value":[1.0,1.0,1.0],"units":"m"},"area":{"value":2.0,"units":"m**2"}},"operating_condition":{"type_name":"AerospaceCondition","private_attribute_constructor":"default","private_attribute_input_cache":{"mach":null,"alpha":null,"beta":null,"thermal_state":null,"reference_mach":null},"alpha":{"value":0.0,"units":"degree"},"beta":{"value":0.0,"units":"degree"},"velocity_magnitude":{"value":50.0,"units":"m/s"},"thermal_state":{"type_name":"ThermalState","private_attribute_constructor":"default","private_attribute_input_cache":{"altitude":null,"temperature_offset":null},"temperature":{"value":288.15,"units":"K"},"density":{"value":1.225,"units":"kg/m**3"},"material":{"type":"air","name":"air","dynamic_viscosity":{"reference_viscosity":{"value":0.00001716,"units":"Pa*s"},"reference_temperature":{"value":273.15,"units":"K"},"effective_temperature":{"value":110.4,"units":"K"}}}},"reference_velocity_magnitude":null},"models":[{"name":null,"type":"Rotation","entities":{"stored_entities":[{"private_attribute_registry_bucket_name":"VolumetricEntityType","private_attribute_entity_type_name":"Cylinder","private_attribute_id":"017e631a-34ae-45f8-96c3-2bb0fa5cf2f2","name":"cylinder","private_attribute_zone_boundary_names":{"items":[]},"private_attribute_full_name":null,"axis":[0.0,1.0,0.0],"center":{"value":[0.0,0.0,0.0],"units":"m"},"height":{"value":2.5,"units":"m"},"inner_radius":{"value":0.0,"units":"m"},"outer_radius":{"value":1.0,"units":"m"}}]},"spec":{"value":"0.0349066*sin(0.05877271*t)","type_name":"AngleExpression"},"parent_volume":null},{"type":"Freestream","entities":{"stored_entities":[{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"GhostSurface","private_attribute_id":null,"name":"farfield","private_attribute_full_name":"__farfield_zone_name_not_properly_set_yet/farfield"}]},"turbulence_quantities":null,"name":"Freestream","velocity":null},{"type":"Wall","entities":{"stored_entities":[{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"Surface","private_attribute_id":null,"name":"wing","private_attribute_full_name":null,"private_attribute_is_interface":null,"private_attribute_tag_key":"faceName","private_attribute_sub_components":["body0001_face0001","body0001_face0002","body0001_face0003","body0001_face0004","body0001_face0005"]}]},"name":"NoSlipWall","use_wall_function":false,"velocity":null,"heat_spec":{"value":{"value":0.0,"units":"W/m**2"},"type_name":"HeatFlux"}},{"material":{"type":"air","name":"air","dynamic_viscosity":{"reference_viscosity":{"value":0.00001716,"units":"Pa*s"},"reference_temperature":{"value":273.15,"units":"K"},"effective_temperature":{"value":110.4,"units":"K"}}},"initial_condition":{"type_name":"NavierStokesInitialCondition","constants":null,"rho":"rho","u":"u","v":"v","w":"w","p":"p"},"type":"Fluid","navier_stokes_solver":{"absolute_tolerance":1e-9,"relative_tolerance":0.0,"order_of_accuracy":2,"equation_evaluation_frequency":1,"linear_solver":{"max_iterations":35,"absolute_tolerance":null,"relative_tolerance":null},"CFL_multiplier":1.0,"kappa_MUSCL":-1.0,"numerical_dissipation_factor":1.0,"limit_velocity":false,"limit_pressure_density":false,"type_name":"Compressible","low_mach_preconditioner":false,"low_mach_preconditioner_threshold":null,"update_jacobian_frequency":4,"max_force_jac_update_physical_steps":0},"turbulence_model_solver":{"absolute_tolerance":1e-8,"relative_tolerance":0.0,"order_of_accuracy":2,"equation_evaluation_frequency":4,"linear_solver":{"max_iterations":25,"absolute_tolerance":null,"relative_tolerance":null},"CFL_multiplier":2.0,"type_name":"SpalartAllmaras","reconstruction_gradient_limiter":0.5,"quadratic_constitutive_relation":false,"modeling_constants":{"type_name":"SpalartAllmarasConsts","C_DES":0.72,"C_d":8.0,"C_cb1":0.1355,"C_cb2":0.622,"C_sigma":0.6666666666666666,"C_v1":7.1,"C_vonKarman":0.41,"C_w2":0.3,"C_t3":1.2,"C_t4":0.5,"C_min_rd":10.0},"update_jacobian_frequency":4,"max_force_jac_update_physical_steps":0,"rotation_correction":false},"transition_model_solver":{"type_name":"None"}}],"time_stepping":{"order_of_accuracy":2,"type_name":"Unsteady","max_pseudo_steps":80,"steps":400,"step_size":{"value":0.0031415926535897933,"units":"s"},"CFL":{"type":"ramp","initial":1.0,"final":100000000.0,"ramp_steps":20}},"user_defined_dynamics":null,"user_defined_fields":[],"outputs":[{"frequency":-1,"frequency_offset":0,"output_format":"paraview","name":"VolumeOutput","output_fields":{"items":["Mach"]},"output_type":"VolumeOutput"},{"frequency":-1,"frequency_offset":0,"output_format":"paraview","name":"SurfaceOutput","entities":{"stored_entities":[{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"Surface","private_attribute_id":null,"name":"wing","private_attribute_full_name":null,"private_attribute_is_interface":null,"private_attribute_tag_key":"faceName","private_attribute_sub_components":["body0001_face0001","body0001_face0002","body0001_face0003","body0001_face0004","body0001_face0005"]}]},"write_single_file":false,"output_fields":{"items":["Cp","CfVec"]},"output_type":"SurfaceOutput"}],"private_attribute_asset_cache":{"project_length_unit":{"value":1.0,"units":"m"},"project_entity_info":{"draft_entities":[{"private_attribute_registry_bucket_name":"VolumetricEntityType","private_attribute_entity_type_name":"Cylinder","private_attribute_id":"017e631a-34ae-45f8-96c3-2bb0fa5cf2f2","name":"cylinder","private_attribute_zone_boundary_names":{"items":[]},"private_attribute_full_name":null,"axis":[0.0,1.0,0.0],"center":{"value":[0.0,0.0,0.0],"units":"m"},"height":{"value":2.5,"units":"m"},"inner_radius":{"value":0.0,"units":"m"},"outer_radius":{"value":1.0,"units":"m"}}],"ghost_entities":[{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"GhostSurface","private_attribute_id":null,"name":"farfield","private_attribute_full_name":null,"type_name":"GhostSphere","center":[0.2500000000000003,0.0,1.2478015079531168e-9],"max_radius":106.00174010911132},{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"GhostCircularPlane","private_attribute_id":null,"name":"symmetric-1","private_attribute_full_name":null,"center":[0.2500000000000003,-1.0600174010911132,1.2478015079531168e-9],"max_radius":2.1200348021822264,"normal_axis":[0,1,0]},{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"GhostCircularPlane","private_attribute_id":null,"name":"symmetric-2","private_attribute_full_name":null,"center":[0.2500000000000003,1.0600174010911132,1.2478015079531168e-9],"max_radius":2.1200348021822264,"normal_axis":[0,1,0]}],"type_name":"GeometryEntityInfo","face_ids":["body0001_face0001","body0001_face0002","body0001_face0003","body0001_face0004","body0001_face0005"],"face_attribute_names":["faceName","groupName","faceId"],"grouped_faces":[[{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"Surface","private_attribute_id":null,"name":"wing","private_attribute_full_name":null,"private_attribute_is_interface":null,"private_attribute_tag_key":"faceName","private_attribute_sub_components":["body0001_face0001","body0001_face0002","body0001_face0003","body0001_face0004","body0001_face0005"]}],[{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"Surface","private_attribute_id":null,"name":"wing","private_attribute_full_name":null,"private_attribute_is_interface":null,"private_attribute_tag_key":"groupName","private_attribute_sub_components":["body0001_face0001","body0001_face0002","body0001_face0003","body0001_face0004","body0001_face0005"]}],[{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"Surface","private_attribute_id":null,"name":"body0001_face0001","private_attribute_full_name":null,"private_attribute_is_interface":null,"private_attribute_tag_key":"faceId","private_attribute_sub_components":["body0001_face0001"]},{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"Surface","private_attribute_id":null,"name":"body0001_face0002","private_attribute_full_name":null,"private_attribute_is_interface":null,"private_attribute_tag_key":"faceId","private_attribute_sub_components":["body0001_face0002"]},{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"Surface","private_attribute_id":null,"name":"body0001_face0003","private_attribute_full_name":null,"private_attribute_is_interface":null,"private_attribute_tag_key":"faceId","private_attribute_sub_components":["body0001_face0003"]},{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"Surface","private_attribute_id":null,"name":"body0001_face0004","private_attribute_full_name":null,"private_attribute_is_interface":null,"private_attribute_tag_key":"faceId","private_attribute_sub_components":["body0001_face0004"]},{"private_attribute_registry_bucket_name":"SurfaceEntityType","private_attribute_entity_type_name":"Surface","private_attribute_id":null,"name":"body0001_face0005","private_attribute_full_name":null,"private_attribute_is_interface":null,"private_attribute_tag_key":"faceId","private_attribute_sub_components":["body0001_face0005"]}]],"edge_ids":["body0001_edge0001","body0001_edge0002","body0001_edge0003","body0001_edge0004","body0001_edge0005","body0001_edge0006","body0001_edge0007","body0001_edge0008","body0001_edge0010","body0001_edge0011","body0001_edge0013"],"edge_attribute_names":["edgeName","edgeId"],"grouped_edges":[[{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"trailingEdge","private_attribute_tag_key":"edgeName","private_attribute_sub_components":["body0001_edge0001","body0001_edge0006"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"leadingEdge","private_attribute_tag_key":"edgeName","private_attribute_sub_components":["body0001_edge0003"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0002","private_attribute_tag_key":"__standalone__","private_attribute_sub_components":["body0001_edge0002"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0004","private_attribute_tag_key":"__standalone__","private_attribute_sub_components":["body0001_edge0004"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0005","private_attribute_tag_key":"__standalone__","private_attribute_sub_components":["body0001_edge0005"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0007","private_attribute_tag_key":"__standalone__","private_attribute_sub_components":["body0001_edge0007"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0008","private_attribute_tag_key":"__standalone__","private_attribute_sub_components":["body0001_edge0008"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0010","private_attribute_tag_key":"__standalone__","private_attribute_sub_components":["body0001_edge0010"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0011","private_attribute_tag_key":"__standalone__","private_attribute_sub_components":["body0001_edge0011"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0013","private_attribute_tag_key":"__standalone__","private_attribute_sub_components":["body0001_edge0013"]}],[{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0001","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0001"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0002","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0002"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0003","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0003"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0004","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0004"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0005","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0005"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0006","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0006"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0007","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0007"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0008","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0008"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0010","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0010"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0011","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0011"]},{"private_attribute_registry_bucket_name":"EdgeEntityType","private_attribute_entity_type_name":"Edge","private_attribute_id":null,"name":"body0001_edge0013","private_attribute_tag_key":"edgeId","private_attribute_sub_components":["body0001_edge0013"]}]],"face_group_tag":"faceName","edge_group_tag":"edgeName"}}}
diff --git a/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/results/X_slicing_forceDistribution.csv b/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/results/X_slicing_forceDistribution.csv
new file mode 100755
index 000000000..e9114a207
--- /dev/null
+++ b/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/results/X_slicing_forceDistribution.csv
@@ -0,0 +1,6 @@
+X,fluid/body00001_face00001_Cumulative_CD_Curve,fluid/body00001_face00002_Cumulative_CD_Curve,fluid/body00001_face00003_Cumulative_CD_Curve,fluid/body00001_face00004_Cumulative_CD_Curve,fluid/body00001_face00005_Cumulative_CD_Curve,fluid/body00001_face00006_Cumulative_CD_Curve,fluid/body00002_face00001_Cumulative_CD_Curve,fluid/body00002_face00002_Cumulative_CD_Curve,fluid/body00002_face00003_Cumulative_CD_Curve,fluid/body00002_face00004_Cumulative_CD_Curve,fluid/body00002_face00005_Cumulative_CD_Curve,fluid/body00002_face00006_Cumulative_CD_Curve,fluid/body00003_face00001_Cumulative_CD_Curve,fluid/body00003_face00002_Cumulative_CD_Curve,fluid/body00003_face00003_Cumulative_CD_Curve,fluid/body00003_face00004_Cumulative_CD_Curve,fluid/body00003_face00005_Cumulative_CD_Curve,fluid/body00003_face00006_Cumulative_CD_Curve,
+0.0,101.0001,201.0001,301.0001,401.0001,501.0001,601.0001,701.0001,801.0001,901.0001,1001.0001,1101.0001,1201.0001,1301.0001,1401.0001,1501.0001,1601.0001,1701.0001,1801.0001,
+0.0001,101.0002,201.0002,301.0002,401.0002,501.0002,601.0002,701.0002,801.0002,901.0002,1001.0002,1101.0002,1201.0002,1301.0002,1401.0002,1501.0002,1601.0002,1701.0002,1801.0002,
+0.0002,101.0003,201.0003,301.0003,401.0003,501.0003,601.0003,701.0003,801.0003,901.0003,1001.0003,1101.0003,1201.0003,1301.0003,1401.0003,1501.0003,1601.0003,1701.0003,1801.0003,
+0.00030000000000000003,101.0004,201.0004,301.0004,401.0004,501.0004,601.0004,701.0004,801.0004,901.0004,1001.0004,1101.0004,1201.0004,1301.0004,1401.0004,1501.0004,1601.0004,1701.0004,1801.0004,
+0.0004,101.0005,201.0005,301.0005,401.0005,501.0005,601.0005,701.0005,801.0005,901.0005,1001.0005,1101.0005,1201.0005,1301.0005,1401.0005,1501.0005,1601.0005,1701.0005,1801.0005,
diff --git a/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/results/Y_slicing_forceDistribution.csv b/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/results/Y_slicing_forceDistribution.csv
new file mode 100755
index 000000000..836e10b1a
--- /dev/null
+++ b/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/results/Y_slicing_forceDistribution.csv
@@ -0,0 +1,6 @@
+Y,fluid/body00001_face00001_CFx_per_span,fluid/body00001_face00001_CFz_per_span,fluid/body00001_face00001_CMy_per_span,fluid/body00001_face00002_CFx_per_span,fluid/body00001_face00002_CFz_per_span,fluid/body00001_face00002_CMy_per_span,fluid/body00001_face00003_CFx_per_span,fluid/body00001_face00003_CFz_per_span,fluid/body00001_face00003_CMy_per_span,fluid/body00001_face00004_CFx_per_span,fluid/body00001_face00004_CFz_per_span,fluid/body00001_face00004_CMy_per_span,fluid/body00001_face00005_CFx_per_span,fluid/body00001_face00005_CFz_per_span,fluid/body00001_face00005_CMy_per_span,fluid/body00001_face00006_CFx_per_span,fluid/body00001_face00006_CFz_per_span,fluid/body00001_face00006_CMy_per_span,fluid/body00002_face00001_CFx_per_span,fluid/body00002_face00001_CFz_per_span,fluid/body00002_face00001_CMy_per_span,fluid/body00002_face00002_CFx_per_span,fluid/body00002_face00002_CFz_per_span,fluid/body00002_face00002_CMy_per_span,fluid/body00002_face00003_CFx_per_span,fluid/body00002_face00003_CFz_per_span,fluid/body00002_face00003_CMy_per_span,fluid/body00002_face00004_CFx_per_span,fluid/body00002_face00004_CFz_per_span,fluid/body00002_face00004_CMy_per_span,fluid/body00002_face00005_CFx_per_span,fluid/body00002_face00005_CFz_per_span,fluid/body00002_face00005_CMy_per_span,fluid/body00002_face00006_CFx_per_span,fluid/body00002_face00006_CFz_per_span,fluid/body00002_face00006_CMy_per_span,fluid/body00003_face00001_CFx_per_span,fluid/body00003_face00001_CFz_per_span,fluid/body00003_face00001_CMy_per_span,fluid/body00003_face00002_CFx_per_span,fluid/body00003_face00002_CFz_per_span,fluid/body00003_face00002_CMy_per_span,fluid/body00003_face00003_CFx_per_span,fluid/body00003_face00003_CFz_per_span,fluid/body00003_face00003_CMy_per_span,fluid/body00003_face00004_CFx_per_span,fluid/body00003_face00004_CFz_per_span,fluid/body00003_face00004_CMy_per_span,fluid/body00003_face00005_CFx_per_span,fluid/body00003_face00005_CFz_per_span,fluid/body00003_face00005_CMy_per_span,fluid/body00003_face00006_CFx_per_span,fluid/body00003_face00006_CFz_per_span,fluid/body00003_face00006_CMy_per_span,
+0.0,101.0001,102.0001,103.0001,201.0001,202.0001,203.0001,301.0001,302.0001,303.0001,401.0001,402.0001,403.0001,501.0001,502.0001,503.0001,601.0001,602.0001,603.0001,701.0001,702.0001,703.0001,801.0001,802.0001,803.0001,901.0001,902.0001,903.0001,1001.0001,1002.0001,1003.0001,1101.0001,1102.0001,1103.0001,1201.0001,1202.0001,1203.0001,1301.0001,1302.0001,1303.0001,1401.0001,1402.0001,1403.0001,1501.0001,1502.0001,1503.0001,1601.0001,1602.0001,1603.0001,1701.0001,1702.0001,1703.0001,1801.0001,1802.0001,1803.0001,
+0.0001,101.0002,102.0002,103.0002,201.0002,202.0002,203.0002,301.0002,302.0002,303.0002,401.0002,402.0002,403.0002,501.0002,502.0002,503.0002,601.0002,602.0002,603.0002,701.0002,702.0002,703.0002,801.0002,802.0002,803.0002,901.0002,902.0002,903.0002,1001.0002,1002.0002,1003.0002,1101.0002,1102.0002,1103.0002,1201.0002,1202.0002,1203.0002,1301.0002,1302.0002,1303.0002,1401.0002,1402.0002,1403.0002,1501.0002,1502.0002,1503.0002,1601.0002,1602.0002,1603.0002,1701.0002,1702.0002,1703.0002,1801.0002,1802.0002,1803.0002,
+0.0002,101.0003,102.0003,103.0003,201.0003,202.0003,203.0003,301.0003,302.0003,303.0003,401.0003,402.0003,403.0003,501.0003,502.0003,503.0003,601.0003,602.0003,603.0003,701.0003,702.0003,703.0003,801.0003,802.0003,803.0003,901.0003,902.0003,903.0003,1001.0003,1002.0003,1003.0003,1101.0003,1102.0003,1103.0003,1201.0003,1202.0003,1203.0003,1301.0003,1302.0003,1303.0003,1401.0003,1402.0003,1403.0003,1501.0003,1502.0003,1503.0003,1601.0003,1602.0003,1603.0003,1701.0003,1702.0003,1703.0003,1801.0003,1802.0003,1803.0003,
+0.00030000000000000003,101.0004,102.0004,103.0004,201.0004,202.0004,203.0004,301.0004,302.0004,303.0004,401.0004,402.0004,403.0004,501.0004,502.0004,503.0004,601.0004,602.0004,603.0004,701.0004,702.0004,703.0004,801.0004,802.0004,803.0004,901.0004,902.0004,903.0004,1001.0004,1002.0004,1003.0004,1101.0004,1102.0004,1103.0004,1201.0004,1202.0004,1203.0004,1301.0004,1302.0004,1303.0004,1401.0004,1402.0004,1403.0004,1501.0004,1502.0004,1503.0004,1601.0004,1602.0004,1603.0004,1701.0004,1702.0004,1703.0004,1801.0004,1802.0004,1803.0004,
+0.0004,101.0005,102.0005,103.0005,201.0005,202.0005,203.0005,301.0005,302.0005,303.0005,401.0005,402.0005,403.0005,501.0005,502.0005,503.0005,601.0005,602.0005,603.0005,701.0005,702.0005,703.0005,801.0005,802.0005,803.0005,901.0005,902.0005,903.0005,1001.0005,1002.0005,1003.0005,1101.0005,1102.0005,1103.0005,1201.0005,1202.0005,1203.0005,1301.0005,1302.0005,1303.0005,1401.0005,1402.0005,1403.0005,1501.0005,1502.0005,1503.0005,1601.0005,1602.0005,1603.0005,1701.0005,1702.0005,1703.0005,1801.0005,1802.0005,1803.0005,
diff --git a/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/results/x_force_dist_by_boundary_reference.csv b/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/results/x_force_dist_by_boundary_reference.csv
new file mode 100644
index 000000000..416be26d0
--- /dev/null
+++ b/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/results/x_force_dist_by_boundary_reference.csv
@@ -0,0 +1,6 @@
+X,Wall-1_Cumulative_CD_Curve,Wall-1_CD_per_strip,Wall-23_Cumulative_CD_Curve,Wall-23_CD_per_strip,totalCumulative_CD_Curve,totalCD_per_strip
+0.0,2106.0006,2106.0006,15012.001199999997,15012.001199999997,17118.0018,17118.0018
+0.0001,2106.0011999999997,0.0005999999998493877,15012.002400000003,0.0012000000060652383,17118.003600000004,0.001800000005914626
+0.0002,2106.0018,0.000600000000304135,15012.003599999998,0.0011999999951513018,17118.0054,0.0017999999954554369
+0.0003,2106.0024,0.0005999999998493877,15012.004800000002,0.0012000000042462489,17118.007200000004,0.0018000000040956365
+0.0004,2106.003,0.000600000000304135,15012.006000000001,0.0011999999987892807,17118.009000000002,0.0017999999990934157
diff --git a/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/results/x_force_dist_reference.csv b/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/results/x_force_dist_reference.csv
new file mode 100644
index 000000000..b96e3953d
--- /dev/null
+++ b/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/results/x_force_dist_reference.csv
@@ -0,0 +1,6 @@
+X,fluid/body00001_face00001_Cumulative_CD_Curve,fluid/body00001_face00002_Cumulative_CD_Curve,fluid/body00001_face00003_Cumulative_CD_Curve,fluid/body00001_face00004_Cumulative_CD_Curve,fluid/body00001_face00005_Cumulative_CD_Curve,fluid/body00001_face00006_Cumulative_CD_Curve,fluid/body00002_face00001_Cumulative_CD_Curve,fluid/body00002_face00002_Cumulative_CD_Curve,fluid/body00002_face00003_Cumulative_CD_Curve,fluid/body00002_face00004_Cumulative_CD_Curve,fluid/body00002_face00005_Cumulative_CD_Curve,fluid/body00002_face00006_Cumulative_CD_Curve,fluid/body00003_face00001_Cumulative_CD_Curve,fluid/body00003_face00002_Cumulative_CD_Curve,fluid/body00003_face00003_Cumulative_CD_Curve,fluid/body00003_face00004_Cumulative_CD_Curve,fluid/body00003_face00005_Cumulative_CD_Curve,fluid/body00003_face00006_Cumulative_CD_Curve,fluid/body00001_face00001_CD_per_strip,fluid/body00001_face00002_CD_per_strip,fluid/body00001_face00003_CD_per_strip,fluid/body00001_face00004_CD_per_strip,fluid/body00001_face00005_CD_per_strip,fluid/body00001_face00006_CD_per_strip,fluid/body00002_face00001_CD_per_strip,fluid/body00002_face00002_CD_per_strip,fluid/body00002_face00003_CD_per_strip,fluid/body00002_face00004_CD_per_strip,fluid/body00002_face00005_CD_per_strip,fluid/body00002_face00006_CD_per_strip,fluid/body00003_face00001_CD_per_strip,fluid/body00003_face00002_CD_per_strip,fluid/body00003_face00003_CD_per_strip,fluid/body00003_face00004_CD_per_strip,fluid/body00003_face00005_CD_per_strip,fluid/body00003_face00006_CD_per_strip,totalCumulative_CD_Curve,totalCD_per_strip
+0.0,101.0001,201.0001,301.0001,401.0001,501.0001,601.0001,701.0001,801.0001,901.0001,1001.0001,1101.0001,1201.0001,1301.0001,1401.0001,1501.0001,1601.0001,1701.0001,1801.0001,101.0001,201.0001,301.0001,401.0001,501.0001,601.0001,701.0001,801.0001,901.0001,1001.0001,1101.0001,1201.0001,1301.0001,1401.0001,1501.0001,1601.0001,1701.0001,1801.0001,17118.0018,17118.0018
+0.0001,101.0002,201.0002,301.0002,401.0002,501.0002,601.0002,701.0002,801.0002,901.0002,1001.0002,1101.0002,1201.0002,1301.0002,1401.0002,1501.0002,1601.0002,1701.0002,1801.0002,0.00010000000000331966,0.00010000000000331966,0.00010000000003174137,0.00010000000003174137,0.00010000000003174137,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,17118.003600000004,0.0017999999997755367
+0.0002,101.0003,201.0003,301.0003,401.0003,501.0003,601.0003,701.0003,801.0003,901.0003,1001.0003,1101.0003,1201.0003,1301.0003,1401.0003,1501.0003,1601.0003,1701.0003,1801.0003,9.99999999891088e-05,0.00010000000000331966,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,0.00010000000008858478,0.00010000000008858478,0.00010000000008858478,0.00010000000008858478,0.00010000000008858478,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,17118.0054,0.0018000000001592298
+0.0003,101.0004,201.0004,301.0004,401.0004,501.0004,601.0004,701.0004,801.0004,901.0004,1001.0004,1101.0004,1201.0004,1301.0004,1401.0004,1501.0004,1601.0004,1701.0004,1801.0004,0.00010000000000331966,0.00010000000000331966,0.00010000000003174137,0.00010000000003174137,0.00010000000003174137,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,17118.007200000004,0.0017999999997755367
+0.0004,101.0005,201.0005,301.0005,401.0005,501.0005,601.0005,701.0005,801.0005,901.0005,1001.0005,1101.0005,1201.0005,1301.0005,1401.0005,1501.0005,1601.0005,1701.0005,1801.0005,0.00010000000000331966,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,9.999999997489795e-05,0.00010000000020227162,0.00010000000020227162,0.00010000000020227162,0.00010000000020227162,0.00010000000020227162,0.00010000000020227162,0.00010000000020227162,0.00010000000020227162,17118.009,0.0018000000013955741
diff --git a/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/results/y_force_dist_by_body_reference.csv b/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/results/y_force_dist_by_body_reference.csv
new file mode 100644
index 000000000..19d9cdc91
--- /dev/null
+++ b/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/results/y_force_dist_by_body_reference.csv
@@ -0,0 +1,6 @@
+Y,body00001_CFx_per_span,body00001_CFz_per_span,body00001_CMy_per_span,body00002_CFx_per_span,body00002_CFz_per_span,body00002_CMy_per_span,body00003_CFx_per_span,body00003_CFz_per_span,body00003_CMy_per_span,totalCFx_per_span,totalCFz_per_span,totalCMy_per_span
+0.0,2106.0006,2112.0006,2118.0006,5706.0006,5712.0006,5718.0006,9306.0006,9312.0006,9318.0006,17118.0018,17136.0018,17154.0018
+0.0001,2106.0011999999997,2112.0011999999997,2118.0011999999997,5706.001200000001,5712.001200000001,5718.001200000001,9306.0012,9312.0012,9318.0012,17118.0036,17136.0036,17154.0036
+0.0002,2106.0018,2112.0018,2118.0018,5706.0018,5712.0018,5718.0018,9306.0018,9312.0018,9318.0018,17118.005400000002,17136.005400000002,17154.005400000002
+0.0003,2106.0024,2112.0024,2118.0024,5706.0024,5712.0024,5718.0024,9306.0024,9312.0024,9318.0024,17118.0072,17136.0072,17154.0072
+0.0004,2106.003,2112.003,2118.003,5706.003000000001,5712.003000000001,5718.003000000001,9306.003,9312.003,9318.003,17118.009000000002,17136.009000000002,17154.009000000002
diff --git a/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/results/y_force_dist_reference.csv b/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/results/y_force_dist_reference.csv
new file mode 100644
index 000000000..31fbaf536
--- /dev/null
+++ b/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/results/y_force_dist_reference.csv
@@ -0,0 +1,6 @@
+Y,fluid/body00001_face00001_CFx_per_span,fluid/body00001_face00001_CFz_per_span,fluid/body00001_face00001_CMy_per_span,fluid/body00001_face00002_CFx_per_span,fluid/body00001_face00002_CFz_per_span,fluid/body00001_face00002_CMy_per_span,fluid/body00001_face00003_CFx_per_span,fluid/body00001_face00003_CFz_per_span,fluid/body00001_face00003_CMy_per_span,fluid/body00001_face00004_CFx_per_span,fluid/body00001_face00004_CFz_per_span,fluid/body00001_face00004_CMy_per_span,fluid/body00001_face00005_CFx_per_span,fluid/body00001_face00005_CFz_per_span,fluid/body00001_face00005_CMy_per_span,fluid/body00001_face00006_CFx_per_span,fluid/body00001_face00006_CFz_per_span,fluid/body00001_face00006_CMy_per_span,fluid/body00002_face00001_CFx_per_span,fluid/body00002_face00001_CFz_per_span,fluid/body00002_face00001_CMy_per_span,fluid/body00002_face00002_CFx_per_span,fluid/body00002_face00002_CFz_per_span,fluid/body00002_face00002_CMy_per_span,fluid/body00002_face00003_CFx_per_span,fluid/body00002_face00003_CFz_per_span,fluid/body00002_face00003_CMy_per_span,fluid/body00002_face00004_CFx_per_span,fluid/body00002_face00004_CFz_per_span,fluid/body00002_face00004_CMy_per_span,fluid/body00002_face00005_CFx_per_span,fluid/body00002_face00005_CFz_per_span,fluid/body00002_face00005_CMy_per_span,fluid/body00002_face00006_CFx_per_span,fluid/body00002_face00006_CFz_per_span,fluid/body00002_face00006_CMy_per_span,fluid/body00003_face00001_CFx_per_span,fluid/body00003_face00001_CFz_per_span,fluid/body00003_face00001_CMy_per_span,fluid/body00003_face00002_CFx_per_span,fluid/body00003_face00002_CFz_per_span,fluid/body00003_face00002_CMy_per_span,fluid/body00003_face00003_CFx_per_span,fluid/body00003_face00003_CFz_per_span,fluid/body00003_face00003_CMy_per_span,fluid/body00003_face00004_CFx_per_span,fluid/body00003_face00004_CFz_per_span,fluid/body00003_face00004_CMy_per_span,fluid/body00003_face00005_CFx_per_span,fluid/body00003_face00005_CFz_per_span,fluid/body00003_face00005_CMy_per_span,fluid/body00003_face00006_CFx_per_span,fluid/body00003_face00006_CFz_per_span,fluid/body00003_face00006_CMy_per_span,totalCFx_per_span,totalCFz_per_span,totalCMy_per_span
+0.0,101.0001,102.0001,103.0001,201.0001,202.0001,203.0001,301.0001,302.0001,303.0001,401.0001,402.0001,403.0001,501.0001,502.0001,503.0001,601.0001,602.0001,603.0001,701.0001,702.0001,703.0001,801.0001,802.0001,803.0001,901.0001,902.0001,903.0001,1001.0001,1002.0001,1003.0001,1101.0001,1102.0001,1103.0001,1201.0001,1202.0001,1203.0001,1301.0001,1302.0001,1303.0001,1401.0001,1402.0001,1403.0001,1501.0001,1502.0001,1503.0001,1601.0001,1602.0001,1603.0001,1701.0001,1702.0001,1703.0001,1801.0001,1802.0001,1803.0001,17118.0018,17136.0018,17154.0018
+0.0001,101.0002,102.0002,103.0002,201.0002,202.0002,203.0002,301.0002,302.0002,303.0002,401.0002,402.0002,403.0002,501.0002,502.0002,503.0002,601.0002,602.0002,603.0002,701.0002,702.0002,703.0002,801.0002,802.0002,803.0002,901.0002,902.0002,903.0002,1001.0002,1002.0002,1003.0002,1101.0002,1102.0002,1103.0002,1201.0002,1202.0002,1203.0002,1301.0002,1302.0002,1303.0002,1401.0002,1402.0002,1403.0002,1501.0002,1502.0002,1503.0002,1601.0002,1602.0002,1603.0002,1701.0002,1702.0002,1703.0002,1801.0002,1802.0002,1803.0002,17118.003600000004,17136.003600000004,17154.003600000004
+0.0002,101.0003,102.0003,103.0003,201.0003,202.0003,203.0003,301.0003,302.0003,303.0003,401.0003,402.0003,403.0003,501.0003,502.0003,503.0003,601.0003,602.0003,603.0003,701.0003,702.0003,703.0003,801.0003,802.0003,803.0003,901.0003,902.0003,903.0003,1001.0003,1002.0003,1003.0003,1101.0003,1102.0003,1103.0003,1201.0003,1202.0003,1203.0003,1301.0003,1302.0003,1303.0003,1401.0003,1402.0003,1403.0003,1501.0003,1502.0003,1503.0003,1601.0003,1602.0003,1603.0003,1701.0003,1702.0003,1703.0003,1801.0003,1802.0003,1803.0003,17118.0054,17136.0054,17154.0054
+0.0003,101.0004,102.0004,103.0004,201.0004,202.0004,203.0004,301.0004,302.0004,303.0004,401.0004,402.0004,403.0004,501.0004,502.0004,503.0004,601.0004,602.0004,603.0004,701.0004,702.0004,703.0004,801.0004,802.0004,803.0004,901.0004,902.0004,903.0004,1001.0004,1002.0004,1003.0004,1101.0004,1102.0004,1103.0004,1201.0004,1202.0004,1203.0004,1301.0004,1302.0004,1303.0004,1401.0004,1402.0004,1403.0004,1501.0004,1502.0004,1503.0004,1601.0004,1602.0004,1603.0004,1701.0004,1702.0004,1703.0004,1801.0004,1802.0004,1803.0004,17118.007200000004,17136.007200000004,17154.007200000004
+0.0004,101.0005,102.0005,103.0005,201.0005,202.0005,203.0005,301.0005,302.0005,303.0005,401.0005,402.0005,403.0005,501.0005,502.0005,503.0005,601.0005,602.0005,603.0005,701.0005,702.0005,703.0005,801.0005,802.0005,803.0005,901.0005,902.0005,903.0005,1001.0005,1002.0005,1003.0005,1101.0005,1102.0005,1103.0005,1201.0005,1202.0005,1203.0005,1301.0005,1302.0005,1303.0005,1401.0005,1402.0005,1403.0005,1501.0005,1502.0005,1503.0005,1601.0005,1602.0005,1603.0005,1701.0005,1702.0005,1703.0005,1801.0005,1802.0005,1803.0005,17118.009,17136.009,17154.009
diff --git a/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/simulation.json b/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/simulation.json
new file mode 100755
index 000000000..569f8b2fc
--- /dev/null
+++ b/tests/data/case-b3927b83-8af6-49cf-aa98-00d4f1838941/simulation.json
@@ -0,0 +1,2144 @@
+{
+ "version": "25.6.7",
+ "unit_system": {
+ "name": "SI"
+ },
+ "meshing": {
+ "refinement_factor": 1,
+ "gap_treatment_strength": 0,
+ "defaults": {
+ "surface_edge_growth_rate": 1.2,
+ "boundary_layer_growth_rate": 1.2,
+ "boundary_layer_first_layer_thickness": {
+ "value": 0.3,
+ "units": "m"
+ },
+ "planar_face_tolerance": 0.000001,
+ "surface_max_edge_length": {
+ "value": 0.3,
+ "units": "m"
+ },
+ "curvature_resolution_angle": {
+ "value": 12,
+ "units": "degree"
+ }
+ },
+ "volume_zones": [
+ {
+ "type": "AutomatedFarfield",
+ "name": "Automated Farfield",
+ "method": "auto",
+ "_id": "cc99ffb3-b895-4fb9-b56f-ea213ef74600"
+ }
+ ]
+ },
+ "reference_geometry": {
+ "moment_center": {
+ "value": [
+ 0,
+ 0,
+ 0
+ ],
+ "units": "m"
+ },
+ "moment_length": {
+ "value": [
+ 1,
+ 1,
+ 1
+ ],
+ "units": "m"
+ },
+ "area": {
+ "type_name": "number",
+ "value": 1,
+ "units": "m**2"
+ }
+ },
+ "operating_condition": {
+ "type_name": "AerospaceCondition",
+ "private_attribute_constructor": "default",
+ "velocity_magnitude": {
+ "type_name": "number",
+ "value": 50.001,
+ "units": "m/s"
+ },
+ "alpha": {
+ "value": 0,
+ "units": "degree"
+ },
+ "beta": {
+ "value": 0,
+ "units": "degree"
+ },
+ "thermal_state": {
+ "type_name": "ThermalState",
+ "private_attribute_constructor": "default",
+ "density": {
+ "value": 1.225,
+ "units": "kg/m**3"
+ },
+ "temperature": {
+ "value": 288.15,
+ "units": "K"
+ }
+ }
+ },
+ "models": [
+ {
+ "_id": "be588209-0262-49b2-a1d9-90185b6d5e9a",
+ "material": {
+ "type": "air",
+ "name": "air",
+ "dynamic_viscosity": {
+ "reference_viscosity": {
+ "value": 0.00001716,
+ "units": "Pa*s"
+ },
+ "reference_temperature": {
+ "value": 273.15,
+ "units": "K"
+ },
+ "effective_temperature": {
+ "value": 110.4,
+ "units": "K"
+ }
+ }
+ },
+ "initial_condition": {
+ "type_name": "NavierStokesInitialCondition",
+ "rho": "rho",
+ "u": "u",
+ "v": "v",
+ "w": "w",
+ "p": "p"
+ },
+ "type": "Fluid",
+ "navier_stokes_solver": {
+ "absolute_tolerance": 1e-10,
+ "relative_tolerance": 0,
+ "order_of_accuracy": 2,
+ "equation_evaluation_frequency": 1,
+ "linear_solver": {
+ "max_iterations": 30
+ },
+ "CFL_multiplier": 1,
+ "kappa_MUSCL": -1,
+ "numerical_dissipation_factor": 1,
+ "limit_velocity": false,
+ "limit_pressure_density": false,
+ "type_name": "Compressible",
+ "low_mach_preconditioner": false,
+ "update_jacobian_frequency": 4,
+ "max_force_jac_update_physical_steps": 0
+ },
+ "turbulence_model_solver": {
+ "absolute_tolerance": 1e-8,
+ "relative_tolerance": 0,
+ "order_of_accuracy": 2,
+ "equation_evaluation_frequency": 4,
+ "linear_solver": {
+ "max_iterations": 20
+ },
+ "CFL_multiplier": 2,
+ "type_name": "SpalartAllmaras",
+ "reconstruction_gradient_limiter": 0.5,
+ "quadratic_constitutive_relation": false,
+ "modeling_constants": {
+ "type_name": "SpalartAllmarasConsts",
+ "C_DES": 0.72,
+ "C_d": 8,
+ "C_cb1": 0.1355,
+ "C_cb2": 0.622,
+ "C_sigma": 0.6666666666666666,
+ "C_v1": 7.1,
+ "C_vonKarman": 0.41,
+ "C_w2": 0.3,
+ "C_t3": 1.2,
+ "C_t4": 0.5,
+ "C_min_rd": 10
+ },
+ "update_jacobian_frequency": 4,
+ "max_force_jac_update_physical_steps": 0,
+ "rotation_correction": false
+ },
+ "transition_model_solver": {
+ "type_name": "None"
+ }
+ },
+ {
+ "_id": "8c9a03f1-8e59-4c05-aee8-2852d9693d86",
+ "type": "Wall",
+ "entities": {
+ "stored_entities": [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00001",
+ "name": "body00001_face00001",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00001"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00002",
+ "name": "body00001_face00002",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00002"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00003",
+ "name": "body00001_face00003",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00003"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00004",
+ "name": "body00001_face00004",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00004"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00005",
+ "name": "body00001_face00005",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00005"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00006",
+ "name": "body00001_face00006",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00006"
+ ]
+ }
+ ]
+ },
+ "name": "Wall-1",
+ "use_wall_function": false,
+ "heat_spec": {
+ "value": {
+ "value": 0,
+ "units": "W/m**2"
+ },
+ "type_name": "HeatFlux"
+ },
+ "roughness_height": {
+ "value": 0,
+ "units": "m"
+ },
+ "velocity": null
+ },
+ {
+ "_id": "357d2e33-da1c-450c-abc1-dc5b4b96e1f9",
+ "type": "Freestream",
+ "entities": {
+ "stored_entities": [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "GhostSphere",
+ "private_attribute_id": "farfield",
+ "name": "farfield",
+ "center": [
+ 2.5,
+ 0.39999999999999997,
+ 0.5
+ ],
+ "max_radius": 250,
+ "_id": "8ae37a4b-6970-5d88-aef5-43a1abcc845e"
+ }
+ ]
+ },
+ "name": "Freestream"
+ },
+ {
+ "name": "Wall-23",
+ "type": "Wall",
+ "_id": "3e331d18-1eb3-4d6e-bf6e-e2f5fed552b1",
+ "use_wall_function": false,
+ "heat_spec": {
+ "value": {
+ "value": 0,
+ "units": "kg/s**3"
+ },
+ "type_name": "HeatFlux"
+ },
+ "roughness_height": {
+ "value": 0,
+ "units": "m"
+ },
+ "velocity": null,
+ "entities": {
+ "stored_entities": [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00001",
+ "name": "body00002_face00001",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00002_face00001"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00002",
+ "name": "body00002_face00002",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00002_face00002"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00003",
+ "name": "body00002_face00003",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00002_face00003"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00004",
+ "name": "body00002_face00004",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00002_face00004"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00005",
+ "name": "body00002_face00005",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00002_face00005"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00006",
+ "name": "body00002_face00006",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00002_face00006"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00001",
+ "name": "body00003_face00001",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00003_face00001"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00002",
+ "name": "body00003_face00002",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00003_face00002"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00003",
+ "name": "body00003_face00003",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00003_face00003"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00004",
+ "name": "body00003_face00004",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00003_face00004"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00005",
+ "name": "body00003_face00005",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00003_face00005"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00006",
+ "name": "body00003_face00006",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00003_face00006"
+ ]
+ }
+ ]
+ }
+ }
+ ],
+ "time_stepping": {
+ "type_name": "Steady",
+ "max_steps": 10,
+ "CFL": {
+ "type": "adaptive",
+ "min": 0.1,
+ "max": 10000,
+ "max_relative_change": 1,
+ "convergence_limiting_factor": 0.25
+ }
+ },
+ "private_attribute_asset_cache": {
+ "project_length_unit": {
+ "units": "m",
+ "value": 1
+ },
+ "project_entity_info": {
+ "ghost_entities": [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "GhostSphere",
+ "private_attribute_id": "farfield",
+ "name": "farfield",
+ "center": [
+ 2.5,
+ 0.39999999999999997,
+ 0.5
+ ],
+ "max_radius": 250
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "GhostCircularPlane",
+ "private_attribute_id": "symmetric-1",
+ "name": "symmetric-1",
+ "center": [
+ 2.5,
+ -0.1,
+ 0.5
+ ],
+ "max_radius": 5,
+ "normal_axis": [
+ 0,
+ 1,
+ 0
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "GhostCircularPlane",
+ "private_attribute_id": "symmetric-2",
+ "name": "symmetric-2",
+ "center": [
+ 2.5,
+ 0.8999999999999999,
+ 0.5
+ ],
+ "max_radius": 5,
+ "normal_axis": [
+ 0,
+ 1,
+ 0
+ ]
+ }
+ ],
+ "type_name": "GeometryEntityInfo",
+ "body_ids": [
+ "body00001",
+ "body00002",
+ "body00003"
+ ],
+ "body_attribute_names": [
+ "bodyId",
+ "groupByFile"
+ ],
+ "grouped_bodies": [
+ [
+ {
+ "private_attribute_registry_bucket_name": "GeometryBodyGroupEntityType",
+ "private_attribute_entity_type_name": "GeometryBodyGroup",
+ "private_attribute_id": "body00001",
+ "name": "body00001",
+ "private_attribute_tag_key": "bodyId",
+ "private_attribute_sub_components": [
+ "body00001"
+ ],
+ "transformation": {
+ "angle_of_rotation": {
+ "value": 0,
+ "units": "degree"
+ },
+ "axis_of_rotation": [
+ 1,
+ 0,
+ 0
+ ],
+ "origin": {
+ "value": [
+ 0,
+ 0,
+ 0
+ ],
+ "units": "m"
+ },
+ "scale": [
+ 1,
+ 1,
+ 1
+ ],
+ "translation": {
+ "value": [
+ 0,
+ 0,
+ 0
+ ],
+ "units": "m"
+ },
+ "type_name": "BodyGroupTransformation"
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "GeometryBodyGroupEntityType",
+ "private_attribute_entity_type_name": "GeometryBodyGroup",
+ "private_attribute_id": "body00002",
+ "name": "body00002",
+ "private_attribute_tag_key": "bodyId",
+ "private_attribute_sub_components": [
+ "body00002"
+ ],
+ "transformation": {
+ "angle_of_rotation": {
+ "value": 0,
+ "units": "degree"
+ },
+ "axis_of_rotation": [
+ 1,
+ 0,
+ 0
+ ],
+ "origin": {
+ "value": [
+ 0,
+ 0,
+ 0
+ ],
+ "units": "m"
+ },
+ "scale": [
+ 1,
+ 1,
+ 1
+ ],
+ "translation": {
+ "value": [
+ 0,
+ 0,
+ 0
+ ],
+ "units": "m"
+ },
+ "type_name": "BodyGroupTransformation"
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "GeometryBodyGroupEntityType",
+ "private_attribute_entity_type_name": "GeometryBodyGroup",
+ "private_attribute_id": "body00003",
+ "name": "body00003",
+ "private_attribute_tag_key": "bodyId",
+ "private_attribute_sub_components": [
+ "body00003"
+ ],
+ "transformation": {
+ "angle_of_rotation": {
+ "value": 0,
+ "units": "degree"
+ },
+ "axis_of_rotation": [
+ 1,
+ 0,
+ 0
+ ],
+ "origin": {
+ "value": [
+ 0,
+ 0,
+ 0
+ ],
+ "units": "m"
+ },
+ "scale": [
+ 1,
+ 1,
+ 1
+ ],
+ "translation": {
+ "value": [
+ 0,
+ 0,
+ 0
+ ],
+ "units": "m"
+ },
+ "type_name": "BodyGroupTransformation"
+ }
+ }
+ ],
+ [
+ {
+ "private_attribute_registry_bucket_name": "GeometryBodyGroupEntityType",
+ "private_attribute_entity_type_name": "GeometryBodyGroup",
+ "private_attribute_id": "geo-11321727-9bb1-4fd5-b88d-19f360fb2149_box.csm",
+ "name": "geo-11321727-9bb1-4fd5-b88d-19f360fb2149_box.csm",
+ "private_attribute_tag_key": "groupByFile",
+ "private_attribute_sub_components": [
+ "body00001",
+ "body00002",
+ "body00003"
+ ],
+ "transformation": {
+ "angle_of_rotation": {
+ "value": 0,
+ "units": "degree"
+ },
+ "axis_of_rotation": [
+ 1,
+ 0,
+ 0
+ ],
+ "origin": {
+ "value": [
+ 0,
+ 0,
+ 0
+ ],
+ "units": "m"
+ },
+ "scale": [
+ 1,
+ 1,
+ 1
+ ],
+ "translation": {
+ "value": [
+ 0,
+ 0,
+ 0
+ ],
+ "units": "m"
+ },
+ "type_name": "BodyGroupTransformation"
+ }
+ }
+ ]
+ ],
+ "face_ids": [
+ "body00001_face00001",
+ "body00001_face00002",
+ "body00001_face00003",
+ "body00001_face00004",
+ "body00001_face00005",
+ "body00001_face00006",
+ "body00002_face00001",
+ "body00002_face00002",
+ "body00002_face00003",
+ "body00002_face00004",
+ "body00002_face00005",
+ "body00002_face00006",
+ "body00003_face00001",
+ "body00003_face00002",
+ "body00003_face00003",
+ "body00003_face00004",
+ "body00003_face00005",
+ "body00003_face00006"
+ ],
+ "face_attribute_names": [
+ "ByBody",
+ "ByTheType",
+ "OnlyFirstTwoBoxHave",
+ "RandomName",
+ "groupByBodyId",
+ "faceId"
+ ],
+ "grouped_faces": [
+ [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "Box1",
+ "name": "Box1",
+ "private_attribute_tag_key": "ByBody",
+ "private_attribute_sub_components": [
+ "body00001_face00001",
+ "body00001_face00002",
+ "body00001_face00003",
+ "body00001_face00004",
+ "body00001_face00005",
+ "body00001_face00006"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00001",
+ "name": "body00002_face00001",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00001"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00002",
+ "name": "body00002_face00002",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00002"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00003",
+ "name": "body00002_face00003",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00003"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00004",
+ "name": "body00002_face00004",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00004"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00005",
+ "name": "body00002_face00005",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00005"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00006",
+ "name": "body00002_face00006",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00006"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00001",
+ "name": "body00003_face00001",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00001"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00002",
+ "name": "body00003_face00002",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00002"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00003",
+ "name": "body00003_face00003",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00003"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00004",
+ "name": "body00003_face00004",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00004"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00005",
+ "name": "body00003_face00005",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00005"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00006",
+ "name": "body00003_face00006",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00006"
+ ]
+ }
+ ],
+ [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "IamFaces",
+ "name": "IamFaces",
+ "private_attribute_tag_key": "ByTheType",
+ "private_attribute_sub_components": [
+ "body00001_face00001",
+ "body00001_face00002",
+ "body00001_face00003",
+ "body00001_face00004",
+ "body00001_face00005",
+ "body00001_face00006"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00001",
+ "name": "body00002_face00001",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00001"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00002",
+ "name": "body00002_face00002",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00002"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00003",
+ "name": "body00002_face00003",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00003"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00004",
+ "name": "body00002_face00004",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00004"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00005",
+ "name": "body00002_face00005",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00005"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00006",
+ "name": "body00002_face00006",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00006"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00001",
+ "name": "body00003_face00001",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00001"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00002",
+ "name": "body00003_face00002",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00002"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00003",
+ "name": "body00003_face00003",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00003"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00004",
+ "name": "body00003_face00004",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00004"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00005",
+ "name": "body00003_face00005",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00005"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00006",
+ "name": "body00003_face00006",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00006"
+ ]
+ }
+ ],
+ [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "Yes",
+ "name": "Yes",
+ "private_attribute_tag_key": "OnlyFirstTwoBoxHave",
+ "private_attribute_sub_components": [
+ "body00001_face00001",
+ "body00001_face00002",
+ "body00001_face00003",
+ "body00001_face00004",
+ "body00001_face00005",
+ "body00001_face00006"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00001",
+ "name": "body00002_face00001",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00001"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00002",
+ "name": "body00002_face00002",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00002"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00003",
+ "name": "body00002_face00003",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00003"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00004",
+ "name": "body00002_face00004",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00004"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00005",
+ "name": "body00002_face00005",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00005"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00006",
+ "name": "body00002_face00006",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00006"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00001",
+ "name": "body00003_face00001",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00001"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00002",
+ "name": "body00003_face00002",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00002"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00003",
+ "name": "body00003_face00003",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00003"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00004",
+ "name": "body00003_face00004",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00004"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00005",
+ "name": "body00003_face00005",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00005"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00006",
+ "name": "body00003_face00006",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00006"
+ ]
+ }
+ ],
+ [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "IamIsolated",
+ "name": "IamIsolated",
+ "private_attribute_tag_key": "RandomName",
+ "private_attribute_sub_components": [
+ "body00003_face00003"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00001",
+ "name": "body00001_face00001",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_face00001"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00002",
+ "name": "body00001_face00002",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_face00002"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00003",
+ "name": "body00001_face00003",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_face00003"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00004",
+ "name": "body00001_face00004",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_face00004"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00005",
+ "name": "body00001_face00005",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_face00005"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00006",
+ "name": "body00001_face00006",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_face00006"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00001",
+ "name": "body00002_face00001",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00001"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00002",
+ "name": "body00002_face00002",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00002"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00003",
+ "name": "body00002_face00003",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00003"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00004",
+ "name": "body00002_face00004",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00004"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00005",
+ "name": "body00002_face00005",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00005"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00006",
+ "name": "body00002_face00006",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00002_face00006"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00001",
+ "name": "body00003_face00001",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00001"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00002",
+ "name": "body00003_face00002",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00002"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00004",
+ "name": "body00003_face00004",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00004"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00005",
+ "name": "body00003_face00005",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00005"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00006",
+ "name": "body00003_face00006",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00003_face00006"
+ ]
+ }
+ ],
+ [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001",
+ "name": "body00001",
+ "private_attribute_tag_key": "groupByBodyId",
+ "private_attribute_sub_components": [
+ "body00001_face00001",
+ "body00001_face00002",
+ "body00001_face00003",
+ "body00001_face00004",
+ "body00001_face00005",
+ "body00001_face00006"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002",
+ "name": "body00002",
+ "private_attribute_tag_key": "groupByBodyId",
+ "private_attribute_sub_components": [
+ "body00002_face00001",
+ "body00002_face00002",
+ "body00002_face00003",
+ "body00002_face00004",
+ "body00002_face00005",
+ "body00002_face00006"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003",
+ "name": "body00003",
+ "private_attribute_tag_key": "groupByBodyId",
+ "private_attribute_sub_components": [
+ "body00003_face00001",
+ "body00003_face00002",
+ "body00003_face00003",
+ "body00003_face00004",
+ "body00003_face00005",
+ "body00003_face00006"
+ ]
+ }
+ ],
+ [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00001",
+ "name": "body00001_face00001",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00001"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00002",
+ "name": "body00001_face00002",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00002"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00003",
+ "name": "body00001_face00003",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00003"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00004",
+ "name": "body00001_face00004",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00004"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00005",
+ "name": "body00001_face00005",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00005"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00006",
+ "name": "body00001_face00006",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00006"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00001",
+ "name": "body00002_face00001",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00002_face00001"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00002",
+ "name": "body00002_face00002",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00002_face00002"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00003",
+ "name": "body00002_face00003",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00002_face00003"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00004",
+ "name": "body00002_face00004",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00002_face00004"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00005",
+ "name": "body00002_face00005",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00002_face00005"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00002_face00006",
+ "name": "body00002_face00006",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00002_face00006"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00001",
+ "name": "body00003_face00001",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00003_face00001"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00002",
+ "name": "body00003_face00002",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00003_face00002"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00003",
+ "name": "body00003_face00003",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00003_face00003"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00004",
+ "name": "body00003_face00004",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00003_face00004"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00005",
+ "name": "body00003_face00005",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00003_face00005"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00003_face00006",
+ "name": "body00003_face00006",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00003_face00006"
+ ]
+ }
+ ]
+ ],
+ "edge_ids": [
+ "body00001_edge00001",
+ "body00001_edge00002",
+ "body00001_edge00003",
+ "body00001_edge00004",
+ "body00001_edge00005",
+ "body00001_edge00006",
+ "body00001_edge00007",
+ "body00001_edge00008",
+ "body00001_edge00009",
+ "body00001_edge00010",
+ "body00001_edge00011",
+ "body00001_edge00012",
+ "body00002_edge00001",
+ "body00002_edge00002",
+ "body00002_edge00003",
+ "body00002_edge00004",
+ "body00002_edge00005",
+ "body00002_edge00006",
+ "body00002_edge00007",
+ "body00002_edge00008",
+ "body00002_edge00009",
+ "body00002_edge00010",
+ "body00002_edge00011",
+ "body00002_edge00012",
+ "body00003_edge00001",
+ "body00003_edge00002",
+ "body00003_edge00003",
+ "body00003_edge00004",
+ "body00003_edge00005",
+ "body00003_edge00006",
+ "body00003_edge00007",
+ "body00003_edge00008",
+ "body00003_edge00009",
+ "body00003_edge00010",
+ "body00003_edge00011",
+ "body00003_edge00012"
+ ],
+ "edge_attribute_names": [
+ "ByBody",
+ "ByTheType",
+ "IamFirstEdge",
+ "edgeId"
+ ],
+ "grouped_edges": [
+ [
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "Box1",
+ "name": "Box1",
+ "private_attribute_tag_key": "ByBody",
+ "private_attribute_sub_components": [
+ "body00001_edge00001",
+ "body00001_edge00002",
+ "body00001_edge00003",
+ "body00001_edge00004",
+ "body00001_edge00005",
+ "body00001_edge00006",
+ "body00001_edge00007",
+ "body00001_edge00008",
+ "body00001_edge00009",
+ "body00001_edge00010",
+ "body00001_edge00011",
+ "body00001_edge00012"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "Box2",
+ "name": "Box2",
+ "private_attribute_tag_key": "ByBody",
+ "private_attribute_sub_components": [
+ "body00002_edge00001",
+ "body00002_edge00002",
+ "body00002_edge00003",
+ "body00002_edge00004",
+ "body00002_edge00005",
+ "body00002_edge00006",
+ "body00002_edge00007",
+ "body00002_edge00008",
+ "body00002_edge00009",
+ "body00002_edge00010",
+ "body00002_edge00011",
+ "body00002_edge00012"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "Box3",
+ "name": "Box3",
+ "private_attribute_tag_key": "ByBody",
+ "private_attribute_sub_components": [
+ "body00003_edge00001",
+ "body00003_edge00002",
+ "body00003_edge00003",
+ "body00003_edge00004",
+ "body00003_edge00005",
+ "body00003_edge00006",
+ "body00003_edge00007",
+ "body00003_edge00008",
+ "body00003_edge00009",
+ "body00003_edge00010",
+ "body00003_edge00011",
+ "body00003_edge00012"
+ ]
+ }
+ ],
+ [
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "IamEdges",
+ "name": "IamEdges",
+ "private_attribute_tag_key": "ByTheType",
+ "private_attribute_sub_components": [
+ "body00001_edge00001",
+ "body00001_edge00002",
+ "body00001_edge00003",
+ "body00001_edge00004",
+ "body00001_edge00005",
+ "body00001_edge00006",
+ "body00001_edge00007",
+ "body00001_edge00008",
+ "body00001_edge00009",
+ "body00001_edge00010",
+ "body00001_edge00011",
+ "body00001_edge00012",
+ "body00002_edge00001",
+ "body00002_edge00002",
+ "body00002_edge00003",
+ "body00002_edge00004",
+ "body00002_edge00005",
+ "body00002_edge00006",
+ "body00002_edge00007",
+ "body00002_edge00008",
+ "body00002_edge00009",
+ "body00002_edge00010",
+ "body00002_edge00011",
+ "body00002_edge00012",
+ "body00003_edge00001",
+ "body00003_edge00002",
+ "body00003_edge00003",
+ "body00003_edge00004",
+ "body00003_edge00005",
+ "body00003_edge00006",
+ "body00003_edge00007",
+ "body00003_edge00008",
+ "body00003_edge00009",
+ "body00003_edge00010",
+ "body00003_edge00011",
+ "body00003_edge00012"
+ ]
+ }
+ ],
+ [
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "Yes",
+ "name": "Yes",
+ "private_attribute_tag_key": "IamFirstEdge",
+ "private_attribute_sub_components": [
+ "body00001_edge00001",
+ "body00001_edge00002",
+ "body00001_edge00003",
+ "body00001_edge00004",
+ "body00001_edge00005",
+ "body00001_edge00006",
+ "body00001_edge00007",
+ "body00001_edge00008",
+ "body00001_edge00009",
+ "body00001_edge00010",
+ "body00001_edge00011",
+ "body00001_edge00012",
+ "body00002_edge00001",
+ "body00002_edge00002",
+ "body00002_edge00003",
+ "body00002_edge00004",
+ "body00002_edge00005",
+ "body00002_edge00006",
+ "body00002_edge00007",
+ "body00002_edge00008",
+ "body00002_edge00009",
+ "body00002_edge00010",
+ "body00002_edge00011",
+ "body00002_edge00012",
+ "body00003_edge00001",
+ "body00003_edge00002",
+ "body00003_edge00003",
+ "body00003_edge00004",
+ "body00003_edge00005",
+ "body00003_edge00006",
+ "body00003_edge00007",
+ "body00003_edge00008",
+ "body00003_edge00009",
+ "body00003_edge00010",
+ "body00003_edge00011",
+ "body00003_edge00012"
+ ]
+ }
+ ],
+ [
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00001",
+ "name": "body00001_edge00001",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00001"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00002",
+ "name": "body00001_edge00002",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00002"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00003",
+ "name": "body00001_edge00003",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00003"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00004",
+ "name": "body00001_edge00004",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00004"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00005",
+ "name": "body00001_edge00005",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00005"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00006",
+ "name": "body00001_edge00006",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00006"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00007",
+ "name": "body00001_edge00007",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00007"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00008",
+ "name": "body00001_edge00008",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00008"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00009",
+ "name": "body00001_edge00009",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00009"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00010",
+ "name": "body00001_edge00010",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00010"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00011",
+ "name": "body00001_edge00011",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00011"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00012",
+ "name": "body00001_edge00012",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00012"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00002_edge00001",
+ "name": "body00002_edge00001",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00002_edge00001"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00002_edge00002",
+ "name": "body00002_edge00002",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00002_edge00002"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00002_edge00003",
+ "name": "body00002_edge00003",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00002_edge00003"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00002_edge00004",
+ "name": "body00002_edge00004",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00002_edge00004"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00002_edge00005",
+ "name": "body00002_edge00005",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00002_edge00005"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00002_edge00006",
+ "name": "body00002_edge00006",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00002_edge00006"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00002_edge00007",
+ "name": "body00002_edge00007",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00002_edge00007"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00002_edge00008",
+ "name": "body00002_edge00008",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00002_edge00008"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00002_edge00009",
+ "name": "body00002_edge00009",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00002_edge00009"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00002_edge00010",
+ "name": "body00002_edge00010",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00002_edge00010"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00002_edge00011",
+ "name": "body00002_edge00011",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00002_edge00011"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00002_edge00012",
+ "name": "body00002_edge00012",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00002_edge00012"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00003_edge00001",
+ "name": "body00003_edge00001",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00003_edge00001"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00003_edge00002",
+ "name": "body00003_edge00002",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00003_edge00002"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00003_edge00003",
+ "name": "body00003_edge00003",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00003_edge00003"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00003_edge00004",
+ "name": "body00003_edge00004",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00003_edge00004"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00003_edge00005",
+ "name": "body00003_edge00005",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00003_edge00005"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00003_edge00006",
+ "name": "body00003_edge00006",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00003_edge00006"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00003_edge00007",
+ "name": "body00003_edge00007",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00003_edge00007"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00003_edge00008",
+ "name": "body00003_edge00008",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00003_edge00008"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00003_edge00009",
+ "name": "body00003_edge00009",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00003_edge00009"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00003_edge00010",
+ "name": "body00003_edge00010",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00003_edge00010"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00003_edge00011",
+ "name": "body00003_edge00011",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00003_edge00011"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00003_edge00012",
+ "name": "body00003_edge00012",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00003_edge00012"
+ ]
+ }
+ ]
+ ],
+ "body_group_tag": "bodyId",
+ "face_group_tag": "faceId",
+ "edge_group_tag": "ByBody",
+ "global_bounding_box": [
+ [
+ 0,
+ -0.1,
+ 0
+ ],
+ [
+ 5,
+ 0.8999999999999999,
+ 1
+ ]
+ ]
+ },
+ "use_inhouse_mesher": false,
+ "variable_context": [
+ {
+ "name": "velocity_with_units",
+ "value": {
+ "type_name": "expression",
+ "expression": "solution.velocity",
+ "output_units": "SI_unit_system"
+ }
+ },
+ {
+ "name": "velocity_magnitude_with_units",
+ "value": {
+ "type_name": "expression",
+ "expression": "math.magnitude(solution.velocity)",
+ "output_units": "SI_unit_system"
+ }
+ },
+ {
+ "name": "pressure_with_units",
+ "value": {
+ "type_name": "expression",
+ "expression": "solution.pressure",
+ "output_units": "SI_unit_system"
+ }
+ },
+ {
+ "name": "wall_shear_stress_magnitude_with_units",
+ "value": {
+ "type_name": "expression",
+ "expression": "solution.wall_shear_stress_magnitude",
+ "output_units": "SI_unit_system"
+ }
+ }
+ ]
+ },
+ "user_defined_dynamics": null,
+ "outputs": null
+}
\ No newline at end of file
diff --git a/tests/data/geo-b2ca24af-f60d-4fb3-8120-c653f3e65be6/simulation.json b/tests/data/geo-b2ca24af-f60d-4fb3-8120-c653f3e65be6/simulation.json
new file mode 100644
index 000000000..6055a469e
--- /dev/null
+++ b/tests/data/geo-b2ca24af-f60d-4fb3-8120-c653f3e65be6/simulation.json
@@ -0,0 +1,3431 @@
+{
+ "version": "25.8.0b3",
+ "unit_system": {
+ "name": "SI"
+ },
+ "meshing": {
+ "type": "MeshingParams",
+ "refinement_factor": 1.0,
+ "gap_treatment_strength": 0.0,
+ "defaults": {
+ "geometry_accuracy": {
+ "value": 10.0,
+ "units": "mm"
+ },
+ "surface_edge_growth_rate": 1.2,
+ "boundary_layer_growth_rate": 1.2,
+ "planar_face_tolerance": 1e-06,
+ "surface_max_aspect_ratio": 10.0,
+ "surface_max_adaptation_iterations": 50,
+ "curvature_resolution_angle": {
+ "value": 12.0,
+ "units": "degree"
+ },
+ "preserve_thin_geometry": false
+ },
+ "refinements": [],
+ "volume_zones": [
+ {
+ "type": "AutomatedFarfield",
+ "name": "Farfield",
+ "method": "auto"
+ }
+ ]
+ },
+ "reference_geometry": {
+ "moment_center": {
+ "value": [
+ 0.0,
+ 0.0,
+ 0.0
+ ],
+ "units": "mm"
+ },
+ "moment_length": {
+ "value": [
+ 1.0,
+ 1.0,
+ 1.0
+ ],
+ "units": "mm"
+ },
+ "area": {
+ "type_name": "number",
+ "value": 1.0,
+ "units": "mm**2"
+ }
+ },
+ "operating_condition": {
+ "type_name": "AerospaceCondition",
+ "private_attribute_constructor": "default",
+ "private_attribute_input_cache": {
+ "alpha": {
+ "value": 0.0,
+ "units": "degree"
+ },
+ "beta": {
+ "value": 0.0,
+ "units": "degree"
+ },
+ "thermal_state": {
+ "type_name": "ThermalState",
+ "private_attribute_constructor": "default",
+ "private_attribute_input_cache": {},
+ "temperature": {
+ "value": 288.15,
+ "units": "K"
+ },
+ "density": {
+ "value": 1.225,
+ "units": "kg/m**3"
+ },
+ "material": {
+ "type": "air",
+ "name": "air",
+ "dynamic_viscosity": {
+ "reference_viscosity": {
+ "value": 1.716e-05,
+ "units": "Pa*s"
+ },
+ "reference_temperature": {
+ "value": 273.15,
+ "units": "K"
+ },
+ "effective_temperature": {
+ "value": 110.4,
+ "units": "K"
+ }
+ }
+ }
+ }
+ },
+ "alpha": {
+ "value": 0.0,
+ "units": "degree"
+ },
+ "beta": {
+ "value": 0.0,
+ "units": "degree"
+ },
+ "thermal_state": {
+ "type_name": "ThermalState",
+ "private_attribute_constructor": "default",
+ "private_attribute_input_cache": {},
+ "temperature": {
+ "value": 288.15,
+ "units": "K"
+ },
+ "density": {
+ "value": 1.225,
+ "units": "kg/m**3"
+ },
+ "material": {
+ "type": "air",
+ "name": "air",
+ "dynamic_viscosity": {
+ "reference_viscosity": {
+ "value": 1.716e-05,
+ "units": "Pa*s"
+ },
+ "reference_temperature": {
+ "value": 273.15,
+ "units": "K"
+ },
+ "effective_temperature": {
+ "value": 110.4,
+ "units": "K"
+ }
+ }
+ }
+ }
+ },
+ "models": [
+ {
+ "type": "Wall",
+ "entities": {
+ "stored_entities": [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "name": "*",
+ "private_attribute_sub_components": []
+ }
+ ]
+ },
+ "name": "Wall",
+ "use_wall_function": false,
+ "heat_spec": {
+ "value": {
+ "value": 0.0,
+ "units": "W/m**2"
+ },
+ "type_name": "HeatFlux"
+ },
+ "roughness_height": {
+ "value": 0.0,
+ "units": "mm"
+ }
+ },
+ {
+ "type": "Freestream",
+ "entities": {
+ "stored_entities": [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "GhostSurface",
+ "name": "farfield"
+ }
+ ]
+ },
+ "name": "Freestream"
+ },
+ {
+ "material": {
+ "type": "air",
+ "name": "air",
+ "dynamic_viscosity": {
+ "reference_viscosity": {
+ "value": 1.716e-05,
+ "units": "Pa*s"
+ },
+ "reference_temperature": {
+ "value": 273.15,
+ "units": "K"
+ },
+ "effective_temperature": {
+ "value": 110.4,
+ "units": "K"
+ }
+ }
+ },
+ "initial_condition": {
+ "type_name": "NavierStokesInitialCondition",
+ "rho": "rho",
+ "u": "u",
+ "v": "v",
+ "w": "w",
+ "p": "p"
+ },
+ "type": "Fluid",
+ "navier_stokes_solver": {
+ "absolute_tolerance": 1e-10,
+ "relative_tolerance": 0.0,
+ "order_of_accuracy": 2,
+ "equation_evaluation_frequency": 1,
+ "linear_solver": {
+ "max_iterations": 30
+ },
+ "CFL_multiplier": 1.0,
+ "kappa_MUSCL": -1.0,
+ "numerical_dissipation_factor": 1.0,
+ "limit_velocity": false,
+ "limit_pressure_density": false,
+ "type_name": "Compressible",
+ "low_mach_preconditioner": false,
+ "update_jacobian_frequency": 4,
+ "max_force_jac_update_physical_steps": 0
+ },
+ "turbulence_model_solver": {
+ "absolute_tolerance": 1e-08,
+ "relative_tolerance": 0.0,
+ "order_of_accuracy": 2,
+ "equation_evaluation_frequency": 4,
+ "linear_solver": {
+ "max_iterations": 20
+ },
+ "CFL_multiplier": 2.0,
+ "type_name": "SpalartAllmaras",
+ "reconstruction_gradient_limiter": 0.5,
+ "quadratic_constitutive_relation": false,
+ "modeling_constants": {
+ "type_name": "SpalartAllmarasConsts",
+ "C_DES": 0.72,
+ "C_d": 8.0,
+ "C_cb1": 0.1355,
+ "C_cb2": 0.622,
+ "C_sigma": 0.6666666666666666,
+ "C_v1": 7.1,
+ "C_vonKarman": 0.41,
+ "C_w2": 0.3,
+ "C_w4": 0.21,
+ "C_w5": 1.5,
+ "C_t3": 1.2,
+ "C_t4": 0.5,
+ "C_min_rd": 10.0
+ },
+ "update_jacobian_frequency": 4,
+ "max_force_jac_update_physical_steps": 0,
+ "rotation_correction": false,
+ "low_reynolds_correction": false
+ },
+ "transition_model_solver": {
+ "type_name": "None"
+ }
+ }
+ ],
+ "time_stepping": {
+ "type_name": "Steady",
+ "max_steps": 2000,
+ "CFL": {
+ "type": "adaptive",
+ "min": 0.1,
+ "max": 10000.0,
+ "max_relative_change": 1.0,
+ "convergence_limiting_factor": 0.25
+ }
+ },
+ "user_defined_fields": [],
+ "outputs": [
+ {
+ "output_fields": {
+ "items": [
+ "Cp",
+ "yPlus",
+ "Cf",
+ "CfVec"
+ ]
+ },
+ "private_attribute_id": "806b10fa-b888-4208-9e19-badec6aa42c2",
+ "frequency": -1,
+ "frequency_offset": 0,
+ "output_format": "paraview",
+ "name": "Surface output",
+ "entities": {
+ "stored_entities": [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "name": "*",
+ "private_attribute_sub_components": []
+ }
+ ]
+ },
+ "write_single_file": false,
+ "output_type": "SurfaceOutput"
+ }
+ ],
+ "private_attribute_asset_cache": {
+ "project_length_unit": {
+ "value": 1.0,
+ "units": "mm"
+ },
+ "use_inhouse_mesher": false,
+ "use_geometry_AI": false,
+ "project_entity_info": {
+ "draft_entities": [],
+ "ghost_entities": [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "GhostSphere",
+ "private_attribute_id": "farfield",
+ "name": "farfield",
+ "private_attribute_full_name": null,
+ "center": [
+ 0,
+ 0,
+ 0
+ ],
+ "max_radius": 7684678.07
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "GhostCircularPlane",
+ "private_attribute_id": "symmetric-1",
+ "name": "symmetric-1",
+ "private_attribute_full_name": null,
+ "center": [
+ 25647.3643,
+ -25600.0,
+ 9886.287672999999
+ ],
+ "max_radius": 7684678.07,
+ "normal_axis": [
+ 0,
+ -1,
+ 0
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "GhostCircularPlane",
+ "private_attribute_id": "symmetric-2",
+ "name": "symmetric-2",
+ "private_attribute_full_name": null,
+ "center": [
+ 25647.3643,
+ 25600.0,
+ 9886.287672999999
+ ],
+ "max_radius": 7684678.07,
+ "normal_axis": [
+ 0,
+ 1,
+ 0
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "GhostCircularPlane",
+ "private_attribute_id": "symmetric",
+ "name": "symmetric",
+ "private_attribute_full_name": null,
+ "center": [
+ 25647.3643,
+ 0,
+ 9886.287672999999
+ ],
+ "max_radius": 7684678.07,
+ "normal_axis": [
+ 0,
+ 1,
+ 0
+ ]
+ }
+ ],
+ "type_name": "GeometryEntityInfo",
+ "body_ids": [
+ "f1_no_rad_frame.stl"
+ ],
+ "body_attribute_names": [
+ "bodyId",
+ "groupByFile"
+ ],
+ "grouped_bodies": [
+ [
+ {
+ "private_attribute_registry_bucket_name": "GeometryBodyGroupEntityType",
+ "private_attribute_entity_type_name": "GeometryBodyGroup",
+ "private_attribute_id": "f1_no_rad_frame.stl",
+ "name": "f1_no_rad_frame.stl",
+ "private_attribute_tag_key": "bodyId",
+ "private_attribute_sub_components": [
+ "f1_no_rad_frame.stl"
+ ],
+ "private_attribute_color": null,
+ "transformation": {
+ "type_name": "BodyGroupTransformation",
+ "origin": {
+ "value": [
+ 0,
+ 0,
+ 0
+ ],
+ "units": "m"
+ },
+ "axis_of_rotation": [
+ 1.0,
+ 0.0,
+ 0.0
+ ],
+ "angle_of_rotation": {
+ "value": 0.0,
+ "units": "degree"
+ },
+ "scale": [
+ 1.0,
+ 1.0,
+ 1.0
+ ],
+ "translation": {
+ "value": [
+ 0,
+ 0,
+ 0
+ ],
+ "units": "m"
+ },
+ "private_attribute_matrix": null
+ },
+ "mesh_exterior": true
+ }
+ ],
+ [
+ {
+ "private_attribute_registry_bucket_name": "GeometryBodyGroupEntityType",
+ "private_attribute_entity_type_name": "GeometryBodyGroup",
+ "private_attribute_id": "f1_no_rad_frame.stl",
+ "name": "f1_no_rad_frame.stl",
+ "private_attribute_tag_key": "groupByFile",
+ "private_attribute_sub_components": [
+ "f1_no_rad_frame.stl"
+ ],
+ "private_attribute_color": null,
+ "transformation": {
+ "type_name": "BodyGroupTransformation",
+ "origin": {
+ "value": [
+ 0,
+ 0,
+ 0
+ ],
+ "units": "m"
+ },
+ "axis_of_rotation": [
+ 1.0,
+ 0.0,
+ 0.0
+ ],
+ "angle_of_rotation": {
+ "value": 0.0,
+ "units": "degree"
+ },
+ "scale": [
+ 1.0,
+ 1.0,
+ 1.0
+ ],
+ "translation": {
+ "value": [
+ 0,
+ 0,
+ 0
+ ],
+ "units": "m"
+ },
+ "private_attribute_matrix": null
+ },
+ "mesh_exterior": true
+ }
+ ]
+ ],
+ "face_ids": [
+ "body",
+ "body-aero-camera",
+ "body-camera",
+ "body-front-af",
+ "body-helmet",
+ "body-inner-nlyr",
+ "body-main-rad-duct",
+ "body-mirror",
+ "body-misc",
+ "body-nose",
+ "body-pit",
+ "body-rear-crash-bar",
+ "body-steering-wheel",
+ "diffuser",
+ "eb-engine",
+ "eb-exhaust",
+ "fr-int-brake-duct-lhs",
+ "fr-int-brake-duct-rhs",
+ "fr-int-caketin-lhs",
+ "fr-int-caketin-rhs",
+ "fr-int-winglet-lhs",
+ "fr-int-winglet-rhs",
+ "fr-susp-lwb-lhs",
+ "fr-susp-lwb-rhs",
+ "fr-susp-prod-lhs",
+ "fr-susp-prod-rhs",
+ "fr-susp-trod-lhs",
+ "fr-susp-trod-rhs",
+ "fr-susp-twb-lhs",
+ "fr-susp-twb-rhs",
+ "fr-wh-brake-disc-lhs",
+ "fr-wh-brake-disc-rhs",
+ "fr-wh-cover-OB-lhs",
+ "fr-wh-cover-OB-rhs",
+ "fr-wh-plinth-lhs",
+ "fr-wh-plinth-rhs",
+ "fr-wh-rim-lhs",
+ "fr-wh-rim-rhs",
+ "fr-wh-tyre-lhs",
+ "fr-wh-tyre-rhs",
+ "fw-brackets",
+ "fw-ep",
+ "fw-fine",
+ "fw-flap-1",
+ "fw-flap-2",
+ "fw-mp",
+ "rr-int-brake-duct-lhs",
+ "rr-int-brake-duct-rhs",
+ "rr-int-caketin-lhs",
+ "rr-int-caketin-rhs",
+ "rr-int-vanes-lhs",
+ "rr-int-vanes-rhs",
+ "rr-susp-lwb-lhs",
+ "rr-susp-lwb-rhs",
+ "rr-susp-prod-lhs",
+ "rr-susp-prod-rhs",
+ "rr-susp-trod-lhs",
+ "rr-susp-trod-rhs",
+ "rr-susp-twb-lhs",
+ "rr-susp-twb-rhs",
+ "rr-wh-brake-disc-lhs",
+ "rr-wh-brake-disc-rhs",
+ "rr-wh-cover-OB-lhs",
+ "rr-wh-cover-OB-rhs",
+ "rr-wh-plinth-lhs",
+ "rr-wh-plinth-rhs",
+ "rr-wh-rim-lhs",
+ "rr-wh-rim-rhs",
+ "rr-wh-tyre-lhs",
+ "rr-wh-tyre-rhs",
+ "rw-ep",
+ "rw-flap",
+ "rw-gf",
+ "rw-mp",
+ "rw-pillar",
+ "toint-rad-main-lhs-down",
+ "toint-rad-main-lhs-up",
+ "toint-rad-main-rhs-down",
+ "toint-rad-main-rhs-up",
+ "tunnel::ground",
+ "tunnel::inlet",
+ "tunnel::outlet",
+ "tunnel::sides",
+ "tunnel::top",
+ "uf",
+ "uf-strakes",
+ "velocity-inlet-exhaust-out",
+ "velocity-inlet-fr-int-duct-lhs-out",
+ "velocity-inlet-fr-int-duct-rhs-out",
+ "velocity-inlet-rr-int-duct-lhs-out",
+ "velocity-inlet-rr-int-duct-rhs-out",
+ "velocity-outlet-engine-intake-in",
+ "velocity-outlet-fr-int-duct-lhs-in",
+ "velocity-outlet-fr-int-duct-rhs-in",
+ "velocity-outlet-rr-int-duct-lhs-in",
+ "velocity-outlet-rr-int-duct-rhs-in"
+ ],
+ "face_attribute_names": [
+ "groupByBodyId",
+ "faceId"
+ ],
+ "grouped_faces": [
+ [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "f1_no_rad_frame.stl",
+ "name": "f1_no_rad_frame.stl",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "groupByBodyId",
+ "private_attribute_sub_components": [
+ "body",
+ "body-aero-camera",
+ "body-camera",
+ "body-front-af",
+ "body-helmet",
+ "body-inner-nlyr",
+ "body-main-rad-duct",
+ "body-mirror",
+ "body-misc",
+ "body-nose",
+ "body-pit",
+ "body-rear-crash-bar",
+ "body-steering-wheel",
+ "diffuser",
+ "eb-engine",
+ "eb-exhaust",
+ "fr-int-brake-duct-lhs",
+ "fr-int-brake-duct-rhs",
+ "fr-int-caketin-lhs",
+ "fr-int-caketin-rhs",
+ "fr-int-winglet-lhs",
+ "fr-int-winglet-rhs",
+ "fr-susp-lwb-lhs",
+ "fr-susp-lwb-rhs",
+ "fr-susp-prod-lhs",
+ "fr-susp-prod-rhs",
+ "fr-susp-trod-lhs",
+ "fr-susp-trod-rhs",
+ "fr-susp-twb-lhs",
+ "fr-susp-twb-rhs",
+ "fr-wh-brake-disc-lhs",
+ "fr-wh-brake-disc-rhs",
+ "fr-wh-cover-OB-lhs",
+ "fr-wh-cover-OB-rhs",
+ "fr-wh-plinth-lhs",
+ "fr-wh-plinth-rhs",
+ "fr-wh-rim-lhs",
+ "fr-wh-rim-rhs",
+ "fr-wh-tyre-lhs",
+ "fr-wh-tyre-rhs",
+ "fw-brackets",
+ "fw-ep",
+ "fw-fine",
+ "fw-flap-1",
+ "fw-flap-2",
+ "fw-mp",
+ "rr-int-brake-duct-lhs",
+ "rr-int-brake-duct-rhs",
+ "rr-int-caketin-lhs",
+ "rr-int-caketin-rhs",
+ "rr-int-vanes-lhs",
+ "rr-int-vanes-rhs",
+ "rr-susp-lwb-lhs",
+ "rr-susp-lwb-rhs",
+ "rr-susp-prod-lhs",
+ "rr-susp-prod-rhs",
+ "rr-susp-trod-lhs",
+ "rr-susp-trod-rhs",
+ "rr-susp-twb-lhs",
+ "rr-susp-twb-rhs",
+ "rr-wh-brake-disc-lhs",
+ "rr-wh-brake-disc-rhs",
+ "rr-wh-cover-OB-lhs",
+ "rr-wh-cover-OB-rhs",
+ "rr-wh-plinth-lhs",
+ "rr-wh-plinth-rhs",
+ "rr-wh-rim-lhs",
+ "rr-wh-rim-rhs",
+ "rr-wh-tyre-lhs",
+ "rr-wh-tyre-rhs",
+ "rw-ep",
+ "rw-flap",
+ "rw-gf",
+ "rw-mp",
+ "rw-pillar",
+ "toint-rad-main-lhs-down",
+ "toint-rad-main-lhs-up",
+ "toint-rad-main-rhs-down",
+ "toint-rad-main-rhs-up",
+ "tunnel::ground",
+ "tunnel::inlet",
+ "tunnel::outlet",
+ "tunnel::sides",
+ "tunnel::top",
+ "uf",
+ "uf-strakes",
+ "velocity-inlet-exhaust-out",
+ "velocity-inlet-fr-int-duct-lhs-out",
+ "velocity-inlet-fr-int-duct-rhs-out",
+ "velocity-inlet-rr-int-duct-lhs-out",
+ "velocity-inlet-rr-int-duct-rhs-out",
+ "velocity-outlet-engine-intake-in",
+ "velocity-outlet-fr-int-duct-lhs-in",
+ "velocity-outlet-fr-int-duct-rhs-in",
+ "velocity-outlet-rr-int-duct-lhs-in",
+ "velocity-outlet-rr-int-duct-rhs-in"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -51199.4164,
+ -25600.0,
+ -479.571754
+ ],
+ [
+ 102494.145,
+ 25600.0,
+ 20252.1471
+ ]
+ ]
+ }
+ }
+ ],
+ [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-wh-brake-disc-lhs",
+ "name": "rr-wh-brake-disc-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-wh-brake-disc-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3528.53613,
+ -804.524292,
+ 224.419952
+ ],
+ [
+ 3768.73926,
+ -767.610718,
+ 465.21582
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-int-winglet-lhs",
+ "name": "fr-int-winglet-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-int-winglet-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 130.478043,
+ -905.53125,
+ 507.116272
+ ],
+ [
+ 275.868744,
+ -586.723389,
+ 767.907349
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-int-brake-duct-lhs",
+ "name": "fr-int-brake-duct-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-int-brake-duct-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -18.4428139,
+ -739.646606,
+ 265.103973
+ ],
+ [
+ 404.780579,
+ -504.262573,
+ 468.704041
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-int-caketin-lhs",
+ "name": "fr-int-caketin-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-int-caketin-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -47.7378082,
+ -675.550354,
+ 103.112488
+ ],
+ [
+ 451.499847,
+ -605.055359,
+ 603.143921
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-int-winglet-rhs",
+ "name": "fr-int-winglet-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-int-winglet-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 130.478043,
+ 586.723389,
+ 507.116272
+ ],
+ [
+ 275.868744,
+ 905.53125,
+ 767.907349
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-int-brake-duct-rhs",
+ "name": "fr-int-brake-duct-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-int-brake-duct-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -18.4428139,
+ 504.262573,
+ 265.103973
+ ],
+ [
+ 404.780579,
+ 739.646606,
+ 468.704041
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-int-caketin-rhs",
+ "name": "fr-int-caketin-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-int-caketin-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -47.7378082,
+ 605.055359,
+ 103.112488
+ ],
+ [
+ 451.499847,
+ 675.550354,
+ 603.143921
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-wh-brake-disc-rhs",
+ "name": "rr-wh-brake-disc-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-wh-brake-disc-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3528.53613,
+ 767.610718,
+ 224.419952
+ ],
+ [
+ 3768.73926,
+ 804.524292,
+ 465.21582
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-wh-rim-rhs",
+ "name": "rr-wh-rim-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-wh-rim-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3613.97632,
+ 927.772949,
+ 314.425476
+ ],
+ [
+ 3681.96411,
+ 989.407898,
+ 382.387024
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-wh-tyre-rhs",
+ "name": "rr-wh-tyre-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-wh-tyre-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3285.27051,
+ 524.285645,
+ -19.0590782
+ ],
+ [
+ 4010.59131,
+ 1006.66284,
+ 706.757629
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-wh-cover-OB-rhs",
+ "name": "rr-wh-cover-OB-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-wh-cover-OB-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3398.85815,
+ 947.596863,
+ 103.490883
+ ],
+ [
+ 3895.13379,
+ 1007.65698,
+ 599.763306
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-susp-prod-lhs",
+ "name": "rr-susp-prod-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-susp-prod-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3492.23975,
+ -638.711853,
+ 204.865982
+ ],
+ [
+ 3660.65845,
+ -109.020988,
+ 336.563782
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-susp-trod-lhs",
+ "name": "rr-susp-trod-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-susp-trod-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3638.37134,
+ -588.224548,
+ 278.633698
+ ],
+ [
+ 3772.90381,
+ -67.5311737,
+ 381.919067
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-susp-prod-rhs",
+ "name": "rr-susp-prod-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-susp-prod-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3492.23975,
+ 109.020988,
+ 204.865982
+ ],
+ [
+ 3660.65845,
+ 638.711853,
+ 336.563782
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-susp-trod-rhs",
+ "name": "rr-susp-trod-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-susp-trod-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3638.37134,
+ 67.5311737,
+ 278.633698
+ ],
+ [
+ 3772.90381,
+ 588.224548,
+ 381.919067
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-susp-lwb-rhs",
+ "name": "rr-susp-lwb-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-susp-lwb-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3087.22388,
+ 57.8537598,
+ 185.083481
+ ],
+ [
+ 3835.37451,
+ 657.063843,
+ 346.585876
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-susp-twb-rhs",
+ "name": "rr-susp-twb-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-susp-twb-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3231.52783,
+ 87.1017914,
+ 320.16684
+ ],
+ [
+ 3737.80615,
+ 577.314026,
+ 411.765198
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-wh-rim-lhs",
+ "name": "rr-wh-rim-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-wh-rim-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3613.97632,
+ -989.407898,
+ 314.425476
+ ],
+ [
+ 3681.96411,
+ -927.772949,
+ 382.387024
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-wh-cover-OB-lhs",
+ "name": "rr-wh-cover-OB-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-wh-cover-OB-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3398.85815,
+ -1007.65698,
+ 103.490883
+ ],
+ [
+ 3895.13379,
+ -947.596863,
+ 599.763306
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-wh-tyre-lhs",
+ "name": "rr-wh-tyre-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-wh-tyre-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3285.27051,
+ -1006.66284,
+ -19.0590782
+ ],
+ [
+ 4010.59131,
+ -524.285645,
+ 706.757629
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-susp-twb-lhs",
+ "name": "rr-susp-twb-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-susp-twb-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3231.52783,
+ -577.314026,
+ 320.16684
+ ],
+ [
+ 3737.80615,
+ -87.1017914,
+ 411.765198
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-susp-lwb-lhs",
+ "name": "rr-susp-lwb-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-susp-lwb-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3087.22388,
+ -657.063843,
+ 185.083481
+ ],
+ [
+ 3835.37451,
+ -57.8537598,
+ 346.585876
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "velocity-outlet-fr-int-duct-lhs-in",
+ "name": "velocity-outlet-fr-int-duct-lhs-in",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "velocity-outlet-fr-int-duct-lhs-in"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -18.2780266,
+ -624.477478,
+ 294.479309
+ ],
+ [
+ -18.0379314,
+ -549.215576,
+ 409.860748
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "velocity-outlet-rr-int-duct-lhs-in",
+ "name": "velocity-outlet-rr-int-duct-lhs-in",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "velocity-outlet-rr-int-duct-lhs-in"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3381.08179,
+ -506.241455,
+ 339.74649
+ ],
+ [
+ 3386.45068,
+ -458.97641,
+ 500.824493
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "velocity-inlet-rr-int-duct-lhs-out",
+ "name": "velocity-inlet-rr-int-duct-lhs-out",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "velocity-inlet-rr-int-duct-lhs-out"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3795.29932,
+ -536.357239,
+ 356.644897
+ ],
+ [
+ 3890.96411,
+ -509.965546,
+ 524.550781
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "velocity-outlet-rr-int-duct-rhs-in",
+ "name": "velocity-outlet-rr-int-duct-rhs-in",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "velocity-outlet-rr-int-duct-rhs-in"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3381.08179,
+ 458.97641,
+ 339.74649
+ ],
+ [
+ 3386.45068,
+ 506.241455,
+ 500.824493
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "velocity-inlet-rr-int-duct-rhs-out",
+ "name": "velocity-inlet-rr-int-duct-rhs-out",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "velocity-inlet-rr-int-duct-rhs-out"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3795.29932,
+ 509.965546,
+ 356.644897
+ ],
+ [
+ 3890.96411,
+ 536.357239,
+ 524.550781
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "velocity-inlet-fr-int-duct-lhs-out",
+ "name": "velocity-inlet-fr-int-duct-lhs-out",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "velocity-inlet-fr-int-duct-lhs-out"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 387.942505,
+ -617.122375,
+ 295.317963
+ ],
+ [
+ 404.739441,
+ -601.971924,
+ 417.000702
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "velocity-outlet-fr-int-duct-rhs-in",
+ "name": "velocity-outlet-fr-int-duct-rhs-in",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "velocity-outlet-fr-int-duct-rhs-in"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -18.2780266,
+ 549.215576,
+ 294.479309
+ ],
+ [
+ -18.0379314,
+ 624.477478,
+ 409.860748
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "velocity-inlet-fr-int-duct-rhs-out",
+ "name": "velocity-inlet-fr-int-duct-rhs-out",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "velocity-inlet-fr-int-duct-rhs-out"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 387.942505,
+ 601.971924,
+ 295.317963
+ ],
+ [
+ 404.739441,
+ 617.122375,
+ 417.000702
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-int-vanes-lhs",
+ "name": "rr-int-vanes-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-int-vanes-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3540.86426,
+ -588.80304,
+ 19.7100334
+ ],
+ [
+ 4001.40381,
+ -410.7836,
+ 346.564362
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-int-caketin-lhs",
+ "name": "rr-int-caketin-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-int-caketin-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3404.07007,
+ -544.245911,
+ 88.9916992
+ ],
+ [
+ 3900.88843,
+ -524.285645,
+ 585.785583
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-int-brake-duct-lhs",
+ "name": "rr-int-brake-duct-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-int-brake-duct-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3380.96558,
+ -596.996582,
+ 336.769257
+ ],
+ [
+ 3891.61572,
+ -456.024445,
+ 538.573975
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-int-vanes-rhs",
+ "name": "rr-int-vanes-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-int-vanes-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3540.86426,
+ 410.7836,
+ 19.7100334
+ ],
+ [
+ 4001.40381,
+ 588.80304,
+ 346.564362
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-int-caketin-rhs",
+ "name": "rr-int-caketin-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-int-caketin-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3404.07007,
+ 524.285645,
+ 88.9916992
+ ],
+ [
+ 3900.88843,
+ 544.245911,
+ 585.785583
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-int-brake-duct-rhs",
+ "name": "rr-int-brake-duct-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-int-brake-duct-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3380.96558,
+ 456.024445,
+ 336.769257
+ ],
+ [
+ 3891.61572,
+ 596.996582,
+ 538.573975
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-susp-trod-lhs",
+ "name": "fr-susp-trod-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-susp-trod-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -32.343914,
+ -659.824585,
+ 342.139618
+ ],
+ [
+ 136.061615,
+ -127.707825,
+ 418.902679
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-wh-brake-disc-lhs",
+ "name": "fr-wh-brake-disc-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-wh-brake-disc-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 82.6637268,
+ -844.129395,
+ 243.654556
+ ],
+ [
+ 322.747253,
+ -800.744324,
+ 484.96344
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-wh-rim-lhs",
+ "name": "fr-wh-rim-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-wh-rim-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 170.600281,
+ -991.287476,
+ 338.5466
+ ],
+ [
+ 238.547424,
+ -928.948364,
+ 406.453278
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-susp-prod-lhs",
+ "name": "fr-susp-prod-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-susp-prod-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 233.320587,
+ -647.498047,
+ 364.649658
+ ],
+ [
+ 341.080322,
+ -121.885841,
+ 547.665649
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-wh-tyre-lhs",
+ "name": "fr-wh-tyre-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-wh-tyre-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -162.240814,
+ -1008.24963,
+ -2.54475045
+ ],
+ [
+ 567.570251,
+ -608.473816,
+ 729.472351
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-wh-cover-OB-lhs",
+ "name": "fr-wh-cover-OB-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-wh-cover-OB-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -40.2233124,
+ -1009.67889,
+ 129.541199
+ ],
+ [
+ 449.751495,
+ -939.006958,
+ 618.820923
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-susp-twb-lhs",
+ "name": "fr-susp-twb-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-susp-twb-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 65.1378555,
+ -705.414734,
+ 470.525513
+ ],
+ [
+ 674.463806,
+ -146.351547,
+ 523.297974
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-susp-lwb-lhs",
+ "name": "fr-susp-lwb-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-susp-lwb-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 21.9377422,
+ -696.497864,
+ 311.893402
+ ],
+ [
+ 631.25531,
+ -137.314163,
+ 359.434753
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-wh-brake-disc-rhs",
+ "name": "fr-wh-brake-disc-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-wh-brake-disc-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 82.6637268,
+ 800.744324,
+ 243.654556
+ ],
+ [
+ 322.747253,
+ 844.129395,
+ 484.96344
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-wh-rim-rhs",
+ "name": "fr-wh-rim-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-wh-rim-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 170.600281,
+ 928.948364,
+ 338.5466
+ ],
+ [
+ 238.547424,
+ 991.287476,
+ 406.453278
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-wh-tyre-rhs",
+ "name": "fr-wh-tyre-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-wh-tyre-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -162.240814,
+ 608.473816,
+ -2.54475045
+ ],
+ [
+ 567.570251,
+ 1008.24963,
+ 729.472351
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-wh-cover-OB-rhs",
+ "name": "fr-wh-cover-OB-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-wh-cover-OB-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -40.2233124,
+ 939.006958,
+ 129.541199
+ ],
+ [
+ 449.751495,
+ 1009.67889,
+ 618.820923
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-susp-twb-rhs",
+ "name": "fr-susp-twb-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-susp-twb-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 65.1378555,
+ 146.351547,
+ 470.525513
+ ],
+ [
+ 674.463806,
+ 705.414734,
+ 523.297974
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-susp-lwb-rhs",
+ "name": "fr-susp-lwb-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-susp-lwb-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 21.9377422,
+ 137.314163,
+ 311.893402
+ ],
+ [
+ 631.25531,
+ 696.497864,
+ 359.434753
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-susp-trod-rhs",
+ "name": "fr-susp-trod-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-susp-trod-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -32.343914,
+ 127.707825,
+ 342.139618
+ ],
+ [
+ 136.061615,
+ 659.824585,
+ 418.902679
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-susp-prod-rhs",
+ "name": "fr-susp-prod-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-susp-prod-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 233.320587,
+ 121.885841,
+ 364.649658
+ ],
+ [
+ 341.080322,
+ 647.498047,
+ 547.665649
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body-front-af",
+ "name": "body-front-af",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body-front-af"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -286.884003,
+ -257.778931,
+ 471.992004
+ ],
+ [
+ -27.3599186,
+ 257.940063,
+ 515.808105
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body-mirror",
+ "name": "body-mirror",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body-mirror"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 1217.56311,
+ -624.887695,
+ 630.0
+ ],
+ [
+ 1416.33704,
+ 624.748535,
+ 733.204956
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body-rear-crash-bar",
+ "name": "body-rear-crash-bar",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body-rear-crash-bar"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3075.84814,
+ -124.042969,
+ 51.6927795
+ ],
+ [
+ 4238.66211,
+ 123.92334,
+ 505.511597
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body-nose",
+ "name": "body-nose",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body-nose"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -1110.39441,
+ -213.967285,
+ 171.416901
+ ],
+ [
+ 937.599487,
+ 213.967285,
+ 630.508484
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body-pit",
+ "name": "body-pit",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body-pit"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 93.6389999,
+ -307.56897,
+ 65.4090576
+ ],
+ [
+ 1986.84497,
+ 307.449341,
+ 688.054932
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body-misc",
+ "name": "body-misc",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body-misc"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 47.7120705,
+ -32.9937744,
+ 364.313019
+ ],
+ [
+ 3589.21216,
+ 32.8741455,
+ 837.305603
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body-aero-camera",
+ "name": "body-aero-camera",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body-aero-camera"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 1990.12012,
+ -131.107178,
+ 972.437866
+ ],
+ [
+ 2212.55811,
+ 131.107788,
+ 1077.61609
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body",
+ "name": "body",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 668.940002,
+ -709.276917,
+ 146.790924
+ ],
+ [
+ 3574.80249,
+ 709.276917,
+ 977.956787
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body-camera",
+ "name": "body-camera",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body-camera"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 2074.57397,
+ -234.837036,
+ 888.095337
+ ],
+ [
+ 2255.86377,
+ 234.837036,
+ 932.726624
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body-inner-nlyr",
+ "name": "body-inner-nlyr",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body-inner-nlyr"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 1665.6521,
+ -706.27948,
+ 160.300827
+ ],
+ [
+ 3573.76782,
+ 706.27948,
+ 729.13739
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body-steering-wheel",
+ "name": "body-steering-wheel",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body-steering-wheel"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 1198.47046,
+ -138.332077,
+ 505.832886
+ ],
+ [
+ 1331.07812,
+ 144.985077,
+ 661.674988
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body-helmet",
+ "name": "body-helmet",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body-helmet"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 1565.5127,
+ -140.424026,
+ 608.354309
+ ],
+ [
+ 1921.86829,
+ 127.111374,
+ 888.247375
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "diffuser",
+ "name": "diffuser",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "diffuser"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 2644.19019,
+ -720.440308,
+ 21.2196312
+ ],
+ [
+ 3991.97485,
+ 720.440308,
+ 348.488983
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "eb-exhaust",
+ "name": "eb-exhaust",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "eb-exhaust"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3468.92798,
+ -52.4777527,
+ 389.730377
+ ],
+ [
+ 4170.2749,
+ 52.4777527,
+ 550.748718
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "velocity-inlet-exhaust-out",
+ "name": "velocity-inlet-exhaust-out",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "velocity-inlet-exhaust-out"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3954.79443,
+ -41.7258301,
+ 437.802002
+ ],
+ [
+ 3961.96875,
+ 41.6550102,
+ 520.770508
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "velocity-outlet-engine-intake-in",
+ "name": "velocity-outlet-engine-intake-in",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "velocity-outlet-engine-intake-in"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 2501.02319,
+ -73.9224548,
+ 728.33667
+ ],
+ [
+ 2572.08179,
+ 73.9239426,
+ 799.237183
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "eb-engine",
+ "name": "eb-engine",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "eb-engine"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 2471.24243,
+ -353.990387,
+ 96.7360992
+ ],
+ [
+ 3469.77515,
+ 353.990387,
+ 494.733337
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fw-ep",
+ "name": "fw-ep",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fw-ep"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -751.499939,
+ -967.758789,
+ 91.8769531
+ ],
+ [
+ -313.960022,
+ 967.619629,
+ 483.095978
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fw-fine",
+ "name": "fw-fine",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fw-fine"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -613.639099,
+ -997.751709,
+ 256.858368
+ ],
+ [
+ -339.892548,
+ 997.751709,
+ 364.61496
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fw-brackets",
+ "name": "fw-brackets",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fw-brackets"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -811.409851,
+ -718.640747,
+ 117.748993
+ ],
+ [
+ -506.989899,
+ 718.501587,
+ 244.408997
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fw-flap-2",
+ "name": "fw-flap-2",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fw-flap-2"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -716.65509,
+ -919.516602,
+ 123.274307
+ ],
+ [
+ -318.399963,
+ 919.516602,
+ 325.514954
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fw-flap-1",
+ "name": "fw-flap-1",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fw-flap-1"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -868.590576,
+ -919.516602,
+ 106.23748
+ ],
+ [
+ -488.7099,
+ 919.516602,
+ 232.348755
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fw-mp",
+ "name": "fw-mp",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fw-mp"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -1038.42041,
+ -898.516846,
+ 91.6744843
+ ],
+ [
+ -613.330017,
+ 898.516846,
+ 200.241943
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "toint-rad-main-lhs-up",
+ "name": "toint-rad-main-lhs-up",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "toint-rad-main-lhs-up"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 1820.08325,
+ -545.423523,
+ 211.815872
+ ],
+ [
+ 2284.84033,
+ -261.048706,
+ 528.243774
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body-main-rad-duct",
+ "name": "body-main-rad-duct",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body-main-rad-duct"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 1665.66272,
+ -595.297302,
+ 203.621841
+ ],
+ [
+ 2306.65625,
+ 595.297302,
+ 558.621887
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "toint-rad-main-rhs-up",
+ "name": "toint-rad-main-rhs-up",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "toint-rad-main-rhs-up"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 1820.08325,
+ 261.048706,
+ 211.815872
+ ],
+ [
+ 2284.84033,
+ 545.423523,
+ 528.243774
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "toint-rad-main-rhs-down",
+ "name": "toint-rad-main-rhs-down",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "toint-rad-main-rhs-down"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 1840.05518,
+ 254.425583,
+ 241.026443
+ ],
+ [
+ 2304.81226,
+ 538.800415,
+ 557.454346
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "toint-rad-main-lhs-down",
+ "name": "toint-rad-main-lhs-down",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "toint-rad-main-lhs-down"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 1840.05518,
+ -538.800415,
+ 241.026443
+ ],
+ [
+ 2304.81226,
+ -254.425583,
+ 557.454346
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rw-ep",
+ "name": "rw-ep",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rw-ep"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3740.35718,
+ -633.95874,
+ 343.771637
+ ],
+ [
+ 4195.57812,
+ 633.839111,
+ 967.431946
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rw-mp",
+ "name": "rw-mp",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rw-mp"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3740.65234,
+ -567.830811,
+ 744.579773
+ ],
+ [
+ 4100.90186,
+ 567.711182,
+ 861.502075
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rw-pillar",
+ "name": "rw-pillar",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rw-pillar"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3637.01025,
+ -16.9159756,
+ 426.376282
+ ],
+ [
+ 4069.29688,
+ 16.8457813,
+ 908.431763
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rw-flap",
+ "name": "rw-flap",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rw-flap"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 4057.47876,
+ -567.739868,
+ 866.495544
+ ],
+ [
+ 4195.57715,
+ 567.739868,
+ 967.418945
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rw-gf",
+ "name": "rw-gf",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rw-gf"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 4186.35303,
+ -567.739868,
+ 966.577332
+ ],
+ [
+ 4195.57617,
+ 567.739868,
+ 973.272095
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "uf-strakes",
+ "name": "uf-strakes",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "uf-strakes"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 907.636963,
+ -739.659058,
+ 30.3602257
+ ],
+ [
+ 2031.8623,
+ 739.659058,
+ 264.314636
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "uf",
+ "name": "uf",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "uf"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 737.347412,
+ -766.421021,
+ 20.384058
+ ],
+ [
+ 3092.76221,
+ 766.421021,
+ 340.326324
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "tunnel::ground",
+ "name": "tunnel::ground",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "tunnel::ground"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -51199.4164,
+ -25600.0,
+ -479.571754
+ ],
+ [
+ 102398.84,
+ 25600.0,
+ 252.374146
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "tunnel::inlet",
+ "name": "tunnel::inlet",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "tunnel::inlet"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -51199.4164,
+ -25600.0,
+ 252.374146
+ ],
+ [
+ -51104.1109,
+ 25600.0,
+ 20252.1471
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "tunnel::outlet",
+ "name": "tunnel::outlet",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "tunnel::outlet"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 102398.84,
+ -25600.0,
+ -479.571754
+ ],
+ [
+ 102494.145,
+ 25600.0,
+ 19520.2012
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "tunnel::sides",
+ "name": "tunnel::sides",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "tunnel::sides"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -51199.4164,
+ -25600.0,
+ -479.571754
+ ],
+ [
+ 102494.145,
+ 25600.0,
+ 20252.1471
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "tunnel::top",
+ "name": "tunnel::top",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "tunnel::top"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ -51104.1109,
+ -25600.0,
+ 19520.2012
+ ],
+ [
+ 102494.145,
+ 25600.0,
+ 20252.1471
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-wh-plinth-lhs",
+ "name": "fr-wh-plinth-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-wh-plinth-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 101.199685,
+ -922.789382,
+ -3.03971537
+ ],
+ [
+ 300.55574,
+ -684.894588,
+ 17.9096002
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fr-wh-plinth-rhs",
+ "name": "fr-wh-plinth-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "fr-wh-plinth-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 101.199685,
+ 684.894588,
+ -3.03971537
+ ],
+ [
+ 300.55574,
+ 922.789382,
+ 17.9096002
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-wh-plinth-lhs",
+ "name": "rr-wh-plinth-lhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-wh-plinth-lhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3547.08768,
+ -923.96201,
+ -19.4631855
+ ],
+ [
+ 3747.00768,
+ -589.461069,
+ 1.48881742
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rr-wh-plinth-rhs",
+ "name": "rr-wh-plinth-rhs",
+ "private_attribute_full_name": null,
+ "private_attribute_is_interface": null,
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "rr-wh-plinth-rhs"
+ ],
+ "private_attribute_color": null,
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 3547.08768,
+ 589.461069,
+ -19.4631855
+ ],
+ [
+ 3747.00768,
+ 923.96201,
+ 1.48881742
+ ]
+ ]
+ }
+ }
+ ]
+ ],
+ "edge_ids": [],
+ "edge_attribute_names": [],
+ "grouped_edges": [],
+ "body_group_tag": "groupByFile",
+ "face_group_tag": "groupByBodyId",
+ "edge_group_tag": null,
+ "global_bounding_box": [
+ [
+ -51199.4164,
+ -25600.0,
+ -479.571754
+ ],
+ [
+ 102494.145,
+ 25600.0,
+ 20252.1471
+ ]
+ ],
+ "default_geometry_accuracy": null
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/data/mock_webapi/project_surface_mesh_simulation_json_resp.json b/tests/data/mock_webapi/project_surface_mesh_simulation_json_resp.json
index d3287432b..625fc41e4 100644
--- a/tests/data/mock_webapi/project_surface_mesh_simulation_json_resp.json
+++ b/tests/data/mock_webapi/project_surface_mesh_simulation_json_resp.json
@@ -1,5 +1,5 @@
{
"data": {
- "simulationJson": "{\"version\":\"24.11.0\",\"unit_system\":{\"name\":\"SI\"},\"meshing\":{\"refinement_factor\":1.0,\"gap_treatment_strength\":0.0,\"defaults\":{\"surface_edge_growth_rate\":1.15,\"boundary_layer_growth_rate\":1.15,\"boundary_layer_first_layer_thickness\":{\"value\":1e-6,\"units\":\"m\"},\"surface_max_edge_length\":{\"value\":0.03,\"units\":\"m\"},\"curvature_resolution_angle\":{\"value\":8.0,\"units\":\"degree\"}},\"refinements\":[{\"name\":\"leadingEdge\",\"refinement_type\":\"SurfaceEdgeRefinement\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"leadingEdge\",\"private_attribute_tag_key\":\"edgeName\",\"private_attribute_sub_components\":[\"body0001_edge0003\"]}]},\"method\":{\"type\":\"angle\",\"value\":{\"value\":1.0,\"units\":\"degree\"}}},{\"name\":\"trailingEdge\",\"refinement_type\":\"SurfaceEdgeRefinement\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"trailingEdge\",\"private_attribute_tag_key\":\"edgeName\",\"private_attribute_sub_components\":[\"body0001_edge0001\",\"body0001_edge0006\"]}]},\"method\":{\"type\":\"height\",\"value\":{\"value\":0.001,\"units\":\"m\"}}}],\"volume_zones\":[{\"spacing_axial\":{\"value\":0.04,\"units\":\"m\"},\"spacing_radial\":{\"value\":0.04,\"units\":\"m\"},\"spacing_circumferential\":{\"value\":0.04,\"units\":\"m\"},\"type\":\"RotationCylinder\",\"name\":null,\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"VolumetricEntityType\",\"private_attribute_entity_type_name\":\"Cylinder\",\"private_attribute_id\":\"017e631a-34ae-45f8-96c3-2bb0fa5cf2f2\",\"name\":\"cylinder\",\"private_attribute_zone_boundary_names\":{\"items\":[]},\"private_attribute_full_name\":null,\"axis\":[0.0,1.0,0.0],\"center\":{\"value\":[0.0,0.0,0.0],\"units\":\"m\"},\"height\":{\"value\":2.5,\"units\":\"m\"},\"inner_radius\":{\"value\":0.0,\"units\":\"m\"},\"outer_radius\":{\"value\":1.0,\"units\":\"m\"}}]},\"enclosed_entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"wing\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceName\",\"private_attribute_sub_components\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"]}]}},{\"type\":\"AutomatedFarfield\",\"name\":\"farfield\",\"method\":\"auto\"}]},\"reference_geometry\":{\"moment_center\":{\"value\":[0.0,0.0,0.0],\"units\":\"m\"},\"moment_length\":{\"value\":[1.0,1.0,1.0],\"units\":\"m\"},\"area\":{\"value\":2.0,\"units\":\"m**2\"}},\"operating_condition\":{\"type_name\":\"AerospaceCondition\",\"private_attribute_constructor\":\"default\",\"private_attribute_input_cache\":{\"mach\":null,\"alpha\":null,\"beta\":null,\"thermal_state\":null,\"reference_mach\":null},\"alpha\":{\"value\":0.0,\"units\":\"degree\"},\"beta\":{\"value\":0.0,\"units\":\"degree\"},\"velocity_magnitude\":{\"value\":50.0,\"units\":\"m/s\"},\"thermal_state\":{\"type_name\":\"ThermalState\",\"private_attribute_constructor\":\"default\",\"private_attribute_input_cache\":{\"altitude\":null,\"temperature_offset\":null},\"temperature\":{\"value\":288.15,\"units\":\"K\"},\"density\":{\"value\":1.225,\"units\":\"kg/m**3\"},\"material\":{\"type\":\"air\",\"name\":\"air\",\"dynamic_viscosity\":{\"reference_viscosity\":{\"value\":0.00001716,\"units\":\"Pa*s\"},\"reference_temperature\":{\"value\":273.15,\"units\":\"K\"},\"effective_temperature\":{\"value\":110.4,\"units\":\"K\"}}}},\"reference_velocity_magnitude\":null},\"models\":[{\"name\":null,\"type\":\"Rotation\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"VolumetricEntityType\",\"private_attribute_entity_type_name\":\"Cylinder\",\"private_attribute_id\":\"017e631a-34ae-45f8-96c3-2bb0fa5cf2f2\",\"name\":\"cylinder\",\"private_attribute_zone_boundary_names\":{\"items\":[]},\"private_attribute_full_name\":null,\"axis\":[0.0,1.0,0.0],\"center\":{\"value\":[0.0,0.0,0.0],\"units\":\"m\"},\"height\":{\"value\":2.5,\"units\":\"m\"},\"inner_radius\":{\"value\":0.0,\"units\":\"m\"},\"outer_radius\":{\"value\":1.0,\"units\":\"m\"}}]},\"spec\":{\"value\":{\"value\":0.0,\"units\":\"rad/s\"},\"type_name\":\"AngularVelocity\"},\"parent_volume\":null},{\"type\":\"Freestream\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"GhostSurface\",\"private_attribute_id\":null,\"name\":\"farfield\",\"private_attribute_full_name\":\"__farfield_zone_name_not_properly_set_yet/farfield\"}]},\"turbulence_quantities\":null,\"name\":\"Freestream\",\"velocity\":null},{\"type\":\"Wall\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"wing\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceName\",\"private_attribute_sub_components\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"]}]},\"name\":\"NoSlipWall\",\"use_wall_function\":false,\"velocity\":null,\"heat_spec\":{\"value\":{\"value\":0.0,\"units\":\"W/m**2\"},\"type_name\":\"HeatFlux\"}},{\"material\":{\"type\":\"air\",\"name\":\"air\",\"dynamic_viscosity\":{\"reference_viscosity\":{\"value\":0.00001716,\"units\":\"Pa*s\"},\"reference_temperature\":{\"value\":273.15,\"units\":\"K\"},\"effective_temperature\":{\"value\":110.4,\"units\":\"K\"}}},\"initial_condition\":{\"type_name\":\"NavierStokesInitialCondition\",\"constants\":null,\"rho\":\"rho\",\"u\":\"u\",\"v\":\"v\",\"w\":\"w\",\"p\":\"p\"},\"type\":\"Fluid\",\"navier_stokes_solver\":{\"absolute_tolerance\":1e-9,\"relative_tolerance\":0.0,\"order_of_accuracy\":2,\"equation_evaluation_frequency\":1,\"linear_solver\":{\"max_iterations\":35,\"absolute_tolerance\":null,\"relative_tolerance\":null},\"CFL_multiplier\":1.0,\"kappa_MUSCL\":-1.0,\"numerical_dissipation_factor\":1.0,\"limit_velocity\":false,\"limit_pressure_density\":false,\"type_name\":\"Compressible\",\"low_mach_preconditioner\":false,\"low_mach_preconditioner_threshold\":null,\"update_jacobian_frequency\":4,\"max_force_jac_update_physical_steps\":0},\"turbulence_model_solver\":{\"absolute_tolerance\":1e-8,\"relative_tolerance\":0.0,\"order_of_accuracy\":2,\"equation_evaluation_frequency\":4,\"linear_solver\":{\"max_iterations\":25,\"absolute_tolerance\":null,\"relative_tolerance\":null},\"CFL_multiplier\":2.0,\"type_name\":\"SpalartAllmaras\",\"DDES\":false,\"grid_size_for_LES\":\"maxEdgeLength\",\"reconstruction_gradient_limiter\":0.5,\"quadratic_constitutive_relation\":false,\"modeling_constants\":{\"type_name\":\"SpalartAllmarasConsts\",\"C_DES\":0.72,\"C_d\":8.0,\"C_cb1\":0.1355,\"C_cb2\":0.622,\"C_sigma\":0.6666666666666666,\"C_v1\":7.1,\"C_vonKarman\":0.41,\"C_w2\":0.3,\"C_t3\":1.2,\"C_t4\":0.5,\"C_min_rd\":10.0},\"update_jacobian_frequency\":4,\"max_force_jac_update_physical_steps\":0,\"rotation_correction\":false},\"transition_model_solver\":{\"type_name\":\"None\"}}],\"time_stepping\":{\"order_of_accuracy\":2,\"type_name\":\"Steady\",\"max_steps\":10000,\"CFL\":{\"type\":\"ramp\",\"initial\":1.0,\"final\":100.0,\"ramp_steps\":1000}},\"user_defined_dynamics\":null,\"user_defined_fields\":[],\"outputs\":[{\"frequency\":-1,\"frequency_offset\":0,\"output_format\":\"paraview\",\"name\":\"VolumeOutput\",\"output_fields\":{\"items\":[\"Mach\"]},\"output_type\":\"VolumeOutput\"},{\"frequency\":-1,\"frequency_offset\":0,\"output_format\":\"paraview\",\"name\":\"SurfaceOutput\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"wing\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceName\",\"private_attribute_sub_components\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"]}]},\"write_single_file\":false,\"output_fields\":{\"items\":[\"Cp\",\"CfVec\"]},\"output_type\":\"SurfaceOutput\"}],\"private_attribute_asset_cache\":{\"project_length_unit\":{\"value\":1.0,\"units\":\"m\"},\"project_entity_info\":{\"draft_entities\":[{\"private_attribute_registry_bucket_name\":\"VolumetricEntityType\",\"private_attribute_entity_type_name\":\"Cylinder\",\"private_attribute_id\":\"017e631a-34ae-45f8-96c3-2bb0fa5cf2f2\",\"name\":\"cylinder\",\"private_attribute_zone_boundary_names\":{\"items\":[]},\"private_attribute_full_name\":null,\"axis\":[0.0,1.0,0.0],\"center\":{\"value\":[0.0,0.0,0.0],\"units\":\"m\"},\"height\":{\"value\":2.5,\"units\":\"m\"},\"inner_radius\":{\"value\":0.0,\"units\":\"m\"},\"outer_radius\":{\"value\":1.0,\"units\":\"m\"}}],\"ghost_entities\":[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"GhostSurface\",\"private_attribute_id\":null,\"name\":\"farfield\",\"private_attribute_full_name\":null,\"type_name\":\"GhostSphere\",\"center\":[0.2500000000000003,0.0,1.2478015079531168e-9],\"max_radius\":106.00174010911132},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"GhostCircularPlane\",\"private_attribute_id\":null,\"name\":\"symmetric-1\",\"private_attribute_full_name\":null,\"center\":[0.2500000000000003,-1.0600174010911132,1.2478015079531168e-9],\"max_radius\":2.1200348021822264,\"normal_axis\":[0,1,0]},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"GhostCircularPlane\",\"private_attribute_id\":null,\"name\":\"symmetric-2\",\"private_attribute_full_name\":null,\"center\":[0.2500000000000003,1.0600174010911132,1.2478015079531168e-9],\"max_radius\":2.1200348021822264,\"normal_axis\":[0,1,0]}],\"type_name\":\"GeometryEntityInfo\",\"face_ids\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"],\"face_attribute_names\":[\"faceName\",\"groupName\",\"faceId\"],\"grouped_faces\":[[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"wing\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceName\",\"private_attribute_sub_components\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"]}],[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"wing\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"groupName\",\"private_attribute_sub_components\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"]}],[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"body0001_face0001\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceId\",\"private_attribute_sub_components\":[\"body0001_face0001\"]},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"body0001_face0002\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceId\",\"private_attribute_sub_components\":[\"body0001_face0002\"]},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"body0001_face0003\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceId\",\"private_attribute_sub_components\":[\"body0001_face0003\"]},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"body0001_face0004\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceId\",\"private_attribute_sub_components\":[\"body0001_face0004\"]},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"body0001_face0005\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceId\",\"private_attribute_sub_components\":[\"body0001_face0005\"]}]],\"edge_ids\":[\"body0001_edge0001\",\"body0001_edge0002\",\"body0001_edge0003\",\"body0001_edge0004\",\"body0001_edge0005\",\"body0001_edge0006\",\"body0001_edge0007\",\"body0001_edge0008\",\"body0001_edge0010\",\"body0001_edge0011\",\"body0001_edge0013\"],\"edge_attribute_names\":[\"edgeName\",\"edgeId\"],\"grouped_edges\":[[{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"trailingEdge\",\"private_attribute_tag_key\":\"edgeName\",\"private_attribute_sub_components\":[\"body0001_edge0001\",\"body0001_edge0006\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"leadingEdge\",\"private_attribute_tag_key\":\"edgeName\",\"private_attribute_sub_components\":[\"body0001_edge0003\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0002\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0002\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0004\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0004\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0005\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0005\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0007\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0007\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0008\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0008\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0010\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0010\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0011\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0011\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0013\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0013\"]}],[{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0001\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0001\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0002\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0002\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0003\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0003\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0004\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0004\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0005\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0005\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0006\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0006\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0007\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0007\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0008\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0008\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0010\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0010\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0011\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0011\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0013\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0013\"]}]],\"face_group_tag\":\"faceName\",\"edge_group_tag\":\"edgeName\"}}}"
+ "simulationJson": "{\"version\":\"24.11.0\",\"unit_system\":{\"name\":\"SI\"},\"meshing\":{\"refinement_factor\":1.0,\"gap_treatment_strength\":0.0,\"defaults\":{\"surface_edge_growth_rate\":1.15,\"boundary_layer_growth_rate\":1.15,\"boundary_layer_first_layer_thickness\":{\"value\":1e-6,\"units\":\"m\"},\"surface_max_edge_length\":{\"value\":0.03,\"units\":\"m\"},\"curvature_resolution_angle\":{\"value\":8.0,\"units\":\"degree\"}},\"refinements\":[{\"name\":\"leadingEdge\",\"refinement_type\":\"SurfaceEdgeRefinement\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"leadingEdge\",\"private_attribute_tag_key\":\"edgeName\",\"private_attribute_sub_components\":[\"body0001_edge0003\"]}]},\"method\":{\"type\":\"angle\",\"value\":{\"value\":1.0,\"units\":\"degree\"}}},{\"name\":\"trailingEdge\",\"refinement_type\":\"SurfaceEdgeRefinement\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"trailingEdge\",\"private_attribute_tag_key\":\"edgeName\",\"private_attribute_sub_components\":[\"body0001_edge0001\",\"body0001_edge0006\"]}]},\"method\":{\"type\":\"height\",\"value\":{\"value\":0.001,\"units\":\"m\"}}}],\"volume_zones\":[{\"spacing_axial\":{\"value\":0.04,\"units\":\"m\"},\"spacing_radial\":{\"value\":0.04,\"units\":\"m\"},\"spacing_circumferential\":{\"value\":0.04,\"units\":\"m\"},\"type\":\"RotationVolume\",\"name\":null,\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"VolumetricEntityType\",\"private_attribute_entity_type_name\":\"Cylinder\",\"private_attribute_id\":\"017e631a-34ae-45f8-96c3-2bb0fa5cf2f2\",\"name\":\"cylinder\",\"private_attribute_zone_boundary_names\":{\"items\":[]},\"private_attribute_full_name\":null,\"axis\":[0.0,1.0,0.0],\"center\":{\"value\":[0.0,0.0,0.0],\"units\":\"m\"},\"height\":{\"value\":2.5,\"units\":\"m\"},\"inner_radius\":{\"value\":0.0,\"units\":\"m\"},\"outer_radius\":{\"value\":1.0,\"units\":\"m\"}}]},\"enclosed_entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"wing\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceName\",\"private_attribute_sub_components\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"]}]}},{\"type\":\"AutomatedFarfield\",\"name\":\"farfield\",\"method\":\"auto\"}]},\"reference_geometry\":{\"moment_center\":{\"value\":[0.0,0.0,0.0],\"units\":\"m\"},\"moment_length\":{\"value\":[1.0,1.0,1.0],\"units\":\"m\"},\"area\":{\"value\":2.0,\"units\":\"m**2\"}},\"operating_condition\":{\"type_name\":\"AerospaceCondition\",\"private_attribute_constructor\":\"default\",\"private_attribute_input_cache\":{\"mach\":null,\"alpha\":null,\"beta\":null,\"thermal_state\":null,\"reference_mach\":null},\"alpha\":{\"value\":0.0,\"units\":\"degree\"},\"beta\":{\"value\":0.0,\"units\":\"degree\"},\"velocity_magnitude\":{\"value\":50.0,\"units\":\"m/s\"},\"thermal_state\":{\"type_name\":\"ThermalState\",\"private_attribute_constructor\":\"default\",\"private_attribute_input_cache\":{\"altitude\":null,\"temperature_offset\":null},\"temperature\":{\"value\":288.15,\"units\":\"K\"},\"density\":{\"value\":1.225,\"units\":\"kg/m**3\"},\"material\":{\"type\":\"air\",\"name\":\"air\",\"dynamic_viscosity\":{\"reference_viscosity\":{\"value\":0.00001716,\"units\":\"Pa*s\"},\"reference_temperature\":{\"value\":273.15,\"units\":\"K\"},\"effective_temperature\":{\"value\":110.4,\"units\":\"K\"}}}},\"reference_velocity_magnitude\":null},\"models\":[{\"name\":null,\"type\":\"Rotation\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"VolumetricEntityType\",\"private_attribute_entity_type_name\":\"Cylinder\",\"private_attribute_id\":\"017e631a-34ae-45f8-96c3-2bb0fa5cf2f2\",\"name\":\"cylinder\",\"private_attribute_zone_boundary_names\":{\"items\":[]},\"private_attribute_full_name\":null,\"axis\":[0.0,1.0,0.0],\"center\":{\"value\":[0.0,0.0,0.0],\"units\":\"m\"},\"height\":{\"value\":2.5,\"units\":\"m\"},\"inner_radius\":{\"value\":0.0,\"units\":\"m\"},\"outer_radius\":{\"value\":1.0,\"units\":\"m\"}}]},\"spec\":{\"value\":{\"value\":0.0,\"units\":\"rad/s\"},\"type_name\":\"AngularVelocity\"},\"parent_volume\":null},{\"type\":\"Freestream\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"GhostSurface\",\"private_attribute_id\":null,\"name\":\"farfield\",\"private_attribute_full_name\":\"__farfield_zone_name_not_properly_set_yet/farfield\"}]},\"turbulence_quantities\":null,\"name\":\"Freestream\",\"velocity\":null},{\"type\":\"Wall\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"wing\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceName\",\"private_attribute_sub_components\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"]}]},\"name\":\"NoSlipWall\",\"use_wall_function\":false,\"velocity\":null,\"heat_spec\":{\"value\":{\"value\":0.0,\"units\":\"W/m**2\"},\"type_name\":\"HeatFlux\"}},{\"material\":{\"type\":\"air\",\"name\":\"air\",\"dynamic_viscosity\":{\"reference_viscosity\":{\"value\":0.00001716,\"units\":\"Pa*s\"},\"reference_temperature\":{\"value\":273.15,\"units\":\"K\"},\"effective_temperature\":{\"value\":110.4,\"units\":\"K\"}}},\"initial_condition\":{\"type_name\":\"NavierStokesInitialCondition\",\"constants\":null,\"rho\":\"rho\",\"u\":\"u\",\"v\":\"v\",\"w\":\"w\",\"p\":\"p\"},\"type\":\"Fluid\",\"navier_stokes_solver\":{\"absolute_tolerance\":1e-9,\"relative_tolerance\":0.0,\"order_of_accuracy\":2,\"equation_evaluation_frequency\":1,\"linear_solver\":{\"max_iterations\":35,\"absolute_tolerance\":null,\"relative_tolerance\":null},\"CFL_multiplier\":1.0,\"kappa_MUSCL\":-1.0,\"numerical_dissipation_factor\":1.0,\"limit_velocity\":false,\"limit_pressure_density\":false,\"type_name\":\"Compressible\",\"low_mach_preconditioner\":false,\"low_mach_preconditioner_threshold\":null,\"update_jacobian_frequency\":4,\"max_force_jac_update_physical_steps\":0},\"turbulence_model_solver\":{\"absolute_tolerance\":1e-8,\"relative_tolerance\":0.0,\"order_of_accuracy\":2,\"equation_evaluation_frequency\":4,\"linear_solver\":{\"max_iterations\":25,\"absolute_tolerance\":null,\"relative_tolerance\":null},\"CFL_multiplier\":2.0,\"type_name\":\"SpalartAllmaras\",\"DDES\":false,\"grid_size_for_LES\":\"maxEdgeLength\",\"reconstruction_gradient_limiter\":0.5,\"quadratic_constitutive_relation\":false,\"modeling_constants\":{\"type_name\":\"SpalartAllmarasConsts\",\"C_DES\":0.72,\"C_d\":8.0,\"C_cb1\":0.1355,\"C_cb2\":0.622,\"C_sigma\":0.6666666666666666,\"C_v1\":7.1,\"C_vonKarman\":0.41,\"C_w2\":0.3,\"C_t3\":1.2,\"C_t4\":0.5,\"C_min_rd\":10.0},\"update_jacobian_frequency\":4,\"max_force_jac_update_physical_steps\":0,\"rotation_correction\":false},\"transition_model_solver\":{\"type_name\":\"None\"}}],\"time_stepping\":{\"order_of_accuracy\":2,\"type_name\":\"Steady\",\"max_steps\":10000,\"CFL\":{\"type\":\"ramp\",\"initial\":1.0,\"final\":100.0,\"ramp_steps\":1000}},\"user_defined_dynamics\":null,\"user_defined_fields\":[],\"outputs\":[{\"frequency\":-1,\"frequency_offset\":0,\"output_format\":\"paraview\",\"name\":\"VolumeOutput\",\"output_fields\":{\"items\":[\"Mach\"]},\"output_type\":\"VolumeOutput\"},{\"frequency\":-1,\"frequency_offset\":0,\"output_format\":\"paraview\",\"name\":\"SurfaceOutput\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"wing\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceName\",\"private_attribute_sub_components\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"]}]},\"write_single_file\":false,\"output_fields\":{\"items\":[\"Cp\",\"CfVec\"]},\"output_type\":\"SurfaceOutput\"}],\"private_attribute_asset_cache\":{\"project_length_unit\":{\"value\":1.0,\"units\":\"m\"},\"project_entity_info\":{\"draft_entities\":[{\"private_attribute_registry_bucket_name\":\"VolumetricEntityType\",\"private_attribute_entity_type_name\":\"Cylinder\",\"private_attribute_id\":\"017e631a-34ae-45f8-96c3-2bb0fa5cf2f2\",\"name\":\"cylinder\",\"private_attribute_zone_boundary_names\":{\"items\":[]},\"private_attribute_full_name\":null,\"axis\":[0.0,1.0,0.0],\"center\":{\"value\":[0.0,0.0,0.0],\"units\":\"m\"},\"height\":{\"value\":2.5,\"units\":\"m\"},\"inner_radius\":{\"value\":0.0,\"units\":\"m\"},\"outer_radius\":{\"value\":1.0,\"units\":\"m\"}}],\"ghost_entities\":[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"GhostSurface\",\"private_attribute_id\":null,\"name\":\"farfield\",\"private_attribute_full_name\":null,\"type_name\":\"GhostSphere\",\"center\":[0.2500000000000003,0.0,1.2478015079531168e-9],\"max_radius\":106.00174010911132},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"GhostCircularPlane\",\"private_attribute_id\":null,\"name\":\"symmetric-1\",\"private_attribute_full_name\":null,\"center\":[0.2500000000000003,-1.0600174010911132,1.2478015079531168e-9],\"max_radius\":2.1200348021822264,\"normal_axis\":[0,1,0]},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"GhostCircularPlane\",\"private_attribute_id\":null,\"name\":\"symmetric-2\",\"private_attribute_full_name\":null,\"center\":[0.2500000000000003,1.0600174010911132,1.2478015079531168e-9],\"max_radius\":2.1200348021822264,\"normal_axis\":[0,1,0]}],\"type_name\":\"GeometryEntityInfo\",\"face_ids\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"],\"face_attribute_names\":[\"faceName\",\"groupName\",\"faceId\"],\"grouped_faces\":[[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"wing\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceName\",\"private_attribute_sub_components\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"]}],[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"wing\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"groupName\",\"private_attribute_sub_components\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"]}],[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"body0001_face0001\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceId\",\"private_attribute_sub_components\":[\"body0001_face0001\"]},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"body0001_face0002\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceId\",\"private_attribute_sub_components\":[\"body0001_face0002\"]},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"body0001_face0003\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceId\",\"private_attribute_sub_components\":[\"body0001_face0003\"]},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"body0001_face0004\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceId\",\"private_attribute_sub_components\":[\"body0001_face0004\"]},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"body0001_face0005\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceId\",\"private_attribute_sub_components\":[\"body0001_face0005\"]}]],\"edge_ids\":[\"body0001_edge0001\",\"body0001_edge0002\",\"body0001_edge0003\",\"body0001_edge0004\",\"body0001_edge0005\",\"body0001_edge0006\",\"body0001_edge0007\",\"body0001_edge0008\",\"body0001_edge0010\",\"body0001_edge0011\",\"body0001_edge0013\"],\"edge_attribute_names\":[\"edgeName\",\"edgeId\"],\"grouped_edges\":[[{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"trailingEdge\",\"private_attribute_tag_key\":\"edgeName\",\"private_attribute_sub_components\":[\"body0001_edge0001\",\"body0001_edge0006\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"leadingEdge\",\"private_attribute_tag_key\":\"edgeName\",\"private_attribute_sub_components\":[\"body0001_edge0003\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0002\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0002\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0004\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0004\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0005\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0005\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0007\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0007\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0008\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0008\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0010\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0010\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0011\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0011\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0013\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0013\"]}],[{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0001\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0001\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0002\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0002\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0003\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0003\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0004\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0004\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0005\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0005\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0006\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0006\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0007\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0007\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0008\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0008\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0010\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0010\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0011\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0011\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0013\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0013\"]}]],\"face_group_tag\":\"faceName\",\"edge_group_tag\":\"edgeName\"}}}"
}
-}
\ No newline at end of file
+}
diff --git a/tests/data/mock_webapi/project_volume_mesh_simulation_json_resp.json b/tests/data/mock_webapi/project_volume_mesh_simulation_json_resp.json
index c35862da7..057629a6a 100644
--- a/tests/data/mock_webapi/project_volume_mesh_simulation_json_resp.json
+++ b/tests/data/mock_webapi/project_volume_mesh_simulation_json_resp.json
@@ -1,5 +1,5 @@
{
"data": {
- "simulationJson": "{\"version\":\"25.2.0\",\"unit_system\":{\"name\":\"SI\"},\"meshing\":{\"refinement_factor\":1.0,\"gap_treatment_strength\":0.0,\"defaults\":{\"surface_edge_growth_rate\":1.15,\"boundary_layer_growth_rate\":1.15,\"boundary_layer_first_layer_thickness\":{\"value\":1e-6,\"units\":\"m\"},\"surface_max_edge_length\":{\"value\":0.03,\"units\":\"m\"},\"curvature_resolution_angle\":{\"value\":8.0,\"units\":\"degree\"}},\"refinements\":[{\"name\":\"leadingEdge\",\"refinement_type\":\"SurfaceEdgeRefinement\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"leadingEdge\",\"private_attribute_tag_key\":\"edgeName\",\"private_attribute_sub_components\":[\"body0001_edge0003\"]}]},\"method\":{\"type\":\"angle\",\"value\":{\"value\":1.0,\"units\":\"degree\"}}},{\"name\":\"trailingEdge\",\"refinement_type\":\"SurfaceEdgeRefinement\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"trailingEdge\",\"private_attribute_tag_key\":\"edgeName\",\"private_attribute_sub_components\":[\"body0001_edge0001\",\"body0001_edge0006\"]}]},\"method\":{\"type\":\"height\",\"value\":{\"value\":0.001,\"units\":\"m\"}}}],\"volume_zones\":[{\"spacing_axial\":{\"value\":0.04,\"units\":\"m\"},\"spacing_radial\":{\"value\":0.04,\"units\":\"m\"},\"spacing_circumferential\":{\"value\":0.04,\"units\":\"m\"},\"type\":\"RotationCylinder\",\"name\":null,\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"VolumetricEntityType\",\"private_attribute_entity_type_name\":\"Cylinder\",\"private_attribute_id\":\"017e631a-34ae-45f8-96c3-2bb0fa5cf2f2\",\"name\":\"cylinder\",\"private_attribute_zone_boundary_names\":{\"items\":[]},\"private_attribute_full_name\":null,\"axis\":[0.0,1.0,0.0],\"center\":{\"value\":[0.0,0.0,0.0],\"units\":\"m\"},\"height\":{\"value\":2.5,\"units\":\"m\"},\"inner_radius\":{\"value\":0.0,\"units\":\"m\"},\"outer_radius\":{\"value\":1.0,\"units\":\"m\"}}]},\"enclosed_entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"wing\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceName\",\"private_attribute_sub_components\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"]}]}},{\"type\":\"AutomatedFarfield\",\"name\":\"farfield\",\"method\":\"auto\"}]},\"reference_geometry\":{\"moment_center\":{\"value\":[0.0,0.0,0.0],\"units\":\"m\"},\"moment_length\":{\"value\":[1.0,1.0,1.0],\"units\":\"m\"},\"area\":{\"value\":2.0,\"units\":\"m**2\"}},\"operating_condition\":{\"type_name\":\"AerospaceCondition\",\"private_attribute_constructor\":\"default\",\"private_attribute_input_cache\":{\"mach\":null,\"alpha\":null,\"beta\":null,\"thermal_state\":null,\"reference_mach\":null},\"alpha\":{\"value\":0.0,\"units\":\"degree\"},\"beta\":{\"value\":0.0,\"units\":\"degree\"},\"velocity_magnitude\":{\"value\":50.0,\"units\":\"m/s\"},\"thermal_state\":{\"type_name\":\"ThermalState\",\"private_attribute_constructor\":\"default\",\"private_attribute_input_cache\":{\"altitude\":null,\"temperature_offset\":null},\"temperature\":{\"value\":288.15,\"units\":\"K\"},\"density\":{\"value\":1.225,\"units\":\"kg/m**3\"},\"material\":{\"type\":\"air\",\"name\":\"air\",\"dynamic_viscosity\":{\"reference_viscosity\":{\"value\":0.00001716,\"units\":\"Pa*s\"},\"reference_temperature\":{\"value\":273.15,\"units\":\"K\"},\"effective_temperature\":{\"value\":110.4,\"units\":\"K\"}}}},\"reference_velocity_magnitude\":null},\"models\":[{\"name\":null,\"type\":\"Rotation\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"VolumetricEntityType\",\"private_attribute_entity_type_name\":\"Cylinder\",\"private_attribute_id\":\"017e631a-34ae-45f8-96c3-2bb0fa5cf2f2\",\"name\":\"cylinder\",\"private_attribute_zone_boundary_names\":{\"items\":[]},\"private_attribute_full_name\":null,\"axis\":[0.0,1.0,0.0],\"center\":{\"value\":[0.0,0.0,0.0],\"units\":\"m\"},\"height\":{\"value\":2.5,\"units\":\"m\"},\"inner_radius\":{\"value\":0.0,\"units\":\"m\"},\"outer_radius\":{\"value\":1.0,\"units\":\"m\"}}]},\"spec\":{\"value\":{\"value\":0.0,\"units\":\"rad/s\"},\"type_name\":\"AngularVelocity\"},\"parent_volume\":null},{\"type\":\"Freestream\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"GhostSurface\",\"private_attribute_id\":null,\"name\":\"farfield\",\"private_attribute_full_name\":\"__farfield_zone_name_not_properly_set_yet/farfield\"}]},\"turbulence_quantities\":null,\"name\":\"Freestream\",\"velocity\":null},{\"type\":\"Wall\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"wing\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceName\",\"private_attribute_sub_components\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"]}]},\"name\":\"NoSlipWall\",\"use_wall_function\":false,\"velocity\":null,\"heat_spec\":{\"value\":{\"value\":0.0,\"units\":\"W/m**2\"},\"type_name\":\"HeatFlux\"}},{\"material\":{\"type\":\"air\",\"name\":\"air\",\"dynamic_viscosity\":{\"reference_viscosity\":{\"value\":0.00001716,\"units\":\"Pa*s\"},\"reference_temperature\":{\"value\":273.15,\"units\":\"K\"},\"effective_temperature\":{\"value\":110.4,\"units\":\"K\"}}},\"initial_condition\":{\"type_name\":\"NavierStokesInitialCondition\",\"constants\":null,\"rho\":\"rho\",\"u\":\"u\",\"v\":\"v\",\"w\":\"w\",\"p\":\"p\"},\"type\":\"Fluid\",\"navier_stokes_solver\":{\"absolute_tolerance\":1e-9,\"relative_tolerance\":0.0,\"order_of_accuracy\":2,\"equation_evaluation_frequency\":1,\"linear_solver\":{\"max_iterations\":35,\"absolute_tolerance\":null,\"relative_tolerance\":null},\"CFL_multiplier\":1.0,\"kappa_MUSCL\":-1.0,\"numerical_dissipation_factor\":1.0,\"limit_velocity\":false,\"limit_pressure_density\":false,\"type_name\":\"Compressible\",\"low_mach_preconditioner\":false,\"low_mach_preconditioner_threshold\":null,\"update_jacobian_frequency\":4,\"max_force_jac_update_physical_steps\":0},\"turbulence_model_solver\":{\"absolute_tolerance\":1e-8,\"relative_tolerance\":0.0,\"order_of_accuracy\":2,\"equation_evaluation_frequency\":4,\"linear_solver\":{\"max_iterations\":25,\"absolute_tolerance\":null,\"relative_tolerance\":null},\"CFL_multiplier\":2.0,\"type_name\":\"SpalartAllmaras\",\"reconstruction_gradient_limiter\":0.5,\"quadratic_constitutive_relation\":false,\"modeling_constants\":{\"type_name\":\"SpalartAllmarasConsts\",\"C_DES\":0.72,\"C_d\":8.0,\"C_cb1\":0.1355,\"C_cb2\":0.622,\"C_sigma\":0.6666666666666666,\"C_v1\":7.1,\"C_vonKarman\":0.41,\"C_w2\":0.3,\"C_t3\":1.2,\"C_t4\":0.5,\"C_min_rd\":10.0},\"update_jacobian_frequency\":4,\"max_force_jac_update_physical_steps\":0,\"rotation_correction\":false},\"transition_model_solver\":{\"type_name\":\"None\"}}],\"time_stepping\":{\"type_name\":\"Steady\",\"max_steps\":10000,\"CFL\":{\"type\":\"ramp\",\"initial\":1.0,\"final\":100.0,\"ramp_steps\":1000}},\"user_defined_dynamics\":null,\"user_defined_fields\":[],\"outputs\":[{\"frequency\":-1,\"frequency_offset\":0,\"output_format\":\"paraview\",\"name\":\"VolumeOutput\",\"output_fields\":{\"items\":[\"Mach\"]},\"output_type\":\"VolumeOutput\"},{\"frequency\":-1,\"frequency_offset\":0,\"output_format\":\"paraview\",\"name\":\"SurfaceOutput\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"wing\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceName\",\"private_attribute_sub_components\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"]}]},\"write_single_file\":false,\"output_fields\":{\"items\":[\"Cp\",\"CfVec\"]},\"output_type\":\"SurfaceOutput\"}],\"private_attribute_asset_cache\":{\"project_length_unit\":{\"value\":1.0,\"units\":\"m\"},\"project_entity_info\":{\"draft_entities\":[{\"private_attribute_registry_bucket_name\":\"VolumetricEntityType\",\"private_attribute_entity_type_name\":\"Cylinder\",\"private_attribute_id\":\"017e631a-34ae-45f8-96c3-2bb0fa5cf2f2\",\"name\":\"cylinder\",\"private_attribute_zone_boundary_names\":{\"items\":[]},\"private_attribute_full_name\":null,\"axis\":[0.0,1.0,0.0],\"center\":{\"value\":[0.0,0.0,0.0],\"units\":\"m\"},\"height\":{\"value\":2.5,\"units\":\"m\"},\"inner_radius\":{\"value\":0.0,\"units\":\"m\"},\"outer_radius\":{\"value\":1.0,\"units\":\"m\"}}],\"ghost_entities\":[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"GhostSurface\",\"private_attribute_id\":null,\"name\":\"farfield\",\"private_attribute_full_name\":null,\"type_name\":\"GhostSphere\",\"center\":[0.2500000000000003,0.0,1.2478015079531168e-9],\"max_radius\":106.00174010911132},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"GhostCircularPlane\",\"private_attribute_id\":null,\"name\":\"symmetric-1\",\"private_attribute_full_name\":null,\"center\":[0.2500000000000003,-1.0600174010911132,1.2478015079531168e-9],\"max_radius\":2.1200348021822264,\"normal_axis\":[0,1,0]},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"GhostCircularPlane\",\"private_attribute_id\":null,\"name\":\"symmetric-2\",\"private_attribute_full_name\":null,\"center\":[0.2500000000000003,1.0600174010911132,1.2478015079531168e-9],\"max_radius\":2.1200348021822264,\"normal_axis\":[0,1,0]}],\"type_name\":\"GeometryEntityInfo\",\"face_ids\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"],\"face_attribute_names\":[\"faceName\",\"groupName\",\"faceId\"],\"grouped_faces\":[[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"wing\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceName\",\"private_attribute_sub_components\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"]}],[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"wing\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"groupName\",\"private_attribute_sub_components\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"]}],[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"body0001_face0001\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceId\",\"private_attribute_sub_components\":[\"body0001_face0001\"]},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"body0001_face0002\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceId\",\"private_attribute_sub_components\":[\"body0001_face0002\"]},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"body0001_face0003\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceId\",\"private_attribute_sub_components\":[\"body0001_face0003\"]},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"body0001_face0004\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceId\",\"private_attribute_sub_components\":[\"body0001_face0004\"]},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"body0001_face0005\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceId\",\"private_attribute_sub_components\":[\"body0001_face0005\"]}]],\"edge_ids\":[\"body0001_edge0001\",\"body0001_edge0002\",\"body0001_edge0003\",\"body0001_edge0004\",\"body0001_edge0005\",\"body0001_edge0006\",\"body0001_edge0007\",\"body0001_edge0008\",\"body0001_edge0010\",\"body0001_edge0011\",\"body0001_edge0013\"],\"edge_attribute_names\":[\"edgeName\",\"edgeId\"],\"grouped_edges\":[[{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"trailingEdge\",\"private_attribute_tag_key\":\"edgeName\",\"private_attribute_sub_components\":[\"body0001_edge0001\",\"body0001_edge0006\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"leadingEdge\",\"private_attribute_tag_key\":\"edgeName\",\"private_attribute_sub_components\":[\"body0001_edge0003\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0002\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0002\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0004\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0004\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0005\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0005\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0007\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0007\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0008\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0008\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0010\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0010\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0011\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0011\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0013\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0013\"]}],[{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0001\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0001\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0002\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0002\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0003\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0003\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0004\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0004\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0005\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0005\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0006\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0006\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0007\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0007\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0008\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0008\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0010\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0010\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0011\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0011\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0013\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0013\"]}]],\"face_group_tag\":\"faceName\",\"edge_group_tag\":\"edgeName\"}}}"
+ "simulationJson": "{\"version\":\"25.2.0\",\"unit_system\":{\"name\":\"SI\"},\"meshing\":{\"refinement_factor\":1.0,\"gap_treatment_strength\":0.0,\"defaults\":{\"surface_edge_growth_rate\":1.15,\"boundary_layer_growth_rate\":1.15,\"boundary_layer_first_layer_thickness\":{\"value\":1e-6,\"units\":\"m\"},\"surface_max_edge_length\":{\"value\":0.03,\"units\":\"m\"},\"curvature_resolution_angle\":{\"value\":8.0,\"units\":\"degree\"}},\"refinements\":[{\"name\":\"leadingEdge\",\"refinement_type\":\"SurfaceEdgeRefinement\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"leadingEdge\",\"private_attribute_tag_key\":\"edgeName\",\"private_attribute_sub_components\":[\"body0001_edge0003\"]}]},\"method\":{\"type\":\"angle\",\"value\":{\"value\":1.0,\"units\":\"degree\"}}},{\"name\":\"trailingEdge\",\"refinement_type\":\"SurfaceEdgeRefinement\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"trailingEdge\",\"private_attribute_tag_key\":\"edgeName\",\"private_attribute_sub_components\":[\"body0001_edge0001\",\"body0001_edge0006\"]}]},\"method\":{\"type\":\"height\",\"value\":{\"value\":0.001,\"units\":\"m\"}}}],\"volume_zones\":[{\"spacing_axial\":{\"value\":0.04,\"units\":\"m\"},\"spacing_radial\":{\"value\":0.04,\"units\":\"m\"},\"spacing_circumferential\":{\"value\":0.04,\"units\":\"m\"},\"type\":\"RotationVolume\",\"name\":null,\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"VolumetricEntityType\",\"private_attribute_entity_type_name\":\"Cylinder\",\"private_attribute_id\":\"017e631a-34ae-45f8-96c3-2bb0fa5cf2f2\",\"name\":\"cylinder\",\"private_attribute_zone_boundary_names\":{\"items\":[]},\"private_attribute_full_name\":null,\"axis\":[0.0,1.0,0.0],\"center\":{\"value\":[0.0,0.0,0.0],\"units\":\"m\"},\"height\":{\"value\":2.5,\"units\":\"m\"},\"inner_radius\":{\"value\":0.0,\"units\":\"m\"},\"outer_radius\":{\"value\":1.0,\"units\":\"m\"}}]},\"enclosed_entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"wing\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceName\",\"private_attribute_sub_components\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"]}]}},{\"type\":\"AutomatedFarfield\",\"name\":\"farfield\",\"method\":\"auto\"}]},\"reference_geometry\":{\"moment_center\":{\"value\":[0.0,0.0,0.0],\"units\":\"m\"},\"moment_length\":{\"value\":[1.0,1.0,1.0],\"units\":\"m\"},\"area\":{\"value\":2.0,\"units\":\"m**2\"}},\"operating_condition\":{\"type_name\":\"AerospaceCondition\",\"private_attribute_constructor\":\"default\",\"private_attribute_input_cache\":{\"mach\":null,\"alpha\":null,\"beta\":null,\"thermal_state\":null,\"reference_mach\":null},\"alpha\":{\"value\":0.0,\"units\":\"degree\"},\"beta\":{\"value\":0.0,\"units\":\"degree\"},\"velocity_magnitude\":{\"value\":50.0,\"units\":\"m/s\"},\"thermal_state\":{\"type_name\":\"ThermalState\",\"private_attribute_constructor\":\"default\",\"private_attribute_input_cache\":{\"altitude\":null,\"temperature_offset\":null},\"temperature\":{\"value\":288.15,\"units\":\"K\"},\"density\":{\"value\":1.225,\"units\":\"kg/m**3\"},\"material\":{\"type\":\"air\",\"name\":\"air\",\"dynamic_viscosity\":{\"reference_viscosity\":{\"value\":0.00001716,\"units\":\"Pa*s\"},\"reference_temperature\":{\"value\":273.15,\"units\":\"K\"},\"effective_temperature\":{\"value\":110.4,\"units\":\"K\"}}}},\"reference_velocity_magnitude\":null},\"models\":[{\"name\":null,\"type\":\"Rotation\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"VolumetricEntityType\",\"private_attribute_entity_type_name\":\"Cylinder\",\"private_attribute_id\":\"017e631a-34ae-45f8-96c3-2bb0fa5cf2f2\",\"name\":\"cylinder\",\"private_attribute_zone_boundary_names\":{\"items\":[]},\"private_attribute_full_name\":null,\"axis\":[0.0,1.0,0.0],\"center\":{\"value\":[0.0,0.0,0.0],\"units\":\"m\"},\"height\":{\"value\":2.5,\"units\":\"m\"},\"inner_radius\":{\"value\":0.0,\"units\":\"m\"},\"outer_radius\":{\"value\":1.0,\"units\":\"m\"}}]},\"spec\":{\"value\":{\"value\":0.0,\"units\":\"rad/s\"},\"type_name\":\"AngularVelocity\"},\"parent_volume\":null},{\"type\":\"Freestream\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"GhostSurface\",\"private_attribute_id\":null,\"name\":\"farfield\",\"private_attribute_full_name\":\"__farfield_zone_name_not_properly_set_yet/farfield\"}]},\"turbulence_quantities\":null,\"name\":\"Freestream\",\"velocity\":null},{\"type\":\"Wall\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"wing\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceName\",\"private_attribute_sub_components\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"]}]},\"name\":\"NoSlipWall\",\"use_wall_function\":false,\"velocity\":null,\"heat_spec\":{\"value\":{\"value\":0.0,\"units\":\"W/m**2\"},\"type_name\":\"HeatFlux\"}},{\"material\":{\"type\":\"air\",\"name\":\"air\",\"dynamic_viscosity\":{\"reference_viscosity\":{\"value\":0.00001716,\"units\":\"Pa*s\"},\"reference_temperature\":{\"value\":273.15,\"units\":\"K\"},\"effective_temperature\":{\"value\":110.4,\"units\":\"K\"}}},\"initial_condition\":{\"type_name\":\"NavierStokesInitialCondition\",\"constants\":null,\"rho\":\"rho\",\"u\":\"u\",\"v\":\"v\",\"w\":\"w\",\"p\":\"p\"},\"type\":\"Fluid\",\"navier_stokes_solver\":{\"absolute_tolerance\":1e-9,\"relative_tolerance\":0.0,\"order_of_accuracy\":2,\"equation_evaluation_frequency\":1,\"linear_solver\":{\"max_iterations\":35,\"absolute_tolerance\":null,\"relative_tolerance\":null},\"CFL_multiplier\":1.0,\"kappa_MUSCL\":-1.0,\"numerical_dissipation_factor\":1.0,\"limit_velocity\":false,\"limit_pressure_density\":false,\"type_name\":\"Compressible\",\"low_mach_preconditioner\":false,\"low_mach_preconditioner_threshold\":null,\"update_jacobian_frequency\":4,\"max_force_jac_update_physical_steps\":0},\"turbulence_model_solver\":{\"absolute_tolerance\":1e-8,\"relative_tolerance\":0.0,\"order_of_accuracy\":2,\"equation_evaluation_frequency\":4,\"linear_solver\":{\"max_iterations\":25,\"absolute_tolerance\":null,\"relative_tolerance\":null},\"CFL_multiplier\":2.0,\"type_name\":\"SpalartAllmaras\",\"reconstruction_gradient_limiter\":0.5,\"quadratic_constitutive_relation\":false,\"modeling_constants\":{\"type_name\":\"SpalartAllmarasConsts\",\"C_DES\":0.72,\"C_d\":8.0,\"C_cb1\":0.1355,\"C_cb2\":0.622,\"C_sigma\":0.6666666666666666,\"C_v1\":7.1,\"C_vonKarman\":0.41,\"C_w2\":0.3,\"C_t3\":1.2,\"C_t4\":0.5,\"C_min_rd\":10.0},\"update_jacobian_frequency\":4,\"max_force_jac_update_physical_steps\":0,\"rotation_correction\":false},\"transition_model_solver\":{\"type_name\":\"None\"}}],\"time_stepping\":{\"type_name\":\"Steady\",\"max_steps\":10000,\"CFL\":{\"type\":\"ramp\",\"initial\":1.0,\"final\":100.0,\"ramp_steps\":1000}},\"user_defined_dynamics\":null,\"user_defined_fields\":[],\"outputs\":[{\"frequency\":-1,\"frequency_offset\":0,\"output_format\":\"paraview\",\"name\":\"VolumeOutput\",\"output_fields\":{\"items\":[\"Mach\"]},\"output_type\":\"VolumeOutput\"},{\"frequency\":-1,\"frequency_offset\":0,\"output_format\":\"paraview\",\"name\":\"SurfaceOutput\",\"entities\":{\"stored_entities\":[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"wing\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceName\",\"private_attribute_sub_components\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"]}]},\"write_single_file\":false,\"output_fields\":{\"items\":[\"Cp\",\"CfVec\"]},\"output_type\":\"SurfaceOutput\"}],\"private_attribute_asset_cache\":{\"project_length_unit\":{\"value\":1.0,\"units\":\"m\"},\"project_entity_info\":{\"draft_entities\":[{\"private_attribute_registry_bucket_name\":\"VolumetricEntityType\",\"private_attribute_entity_type_name\":\"Cylinder\",\"private_attribute_id\":\"017e631a-34ae-45f8-96c3-2bb0fa5cf2f2\",\"name\":\"cylinder\",\"private_attribute_zone_boundary_names\":{\"items\":[]},\"private_attribute_full_name\":null,\"axis\":[0.0,1.0,0.0],\"center\":{\"value\":[0.0,0.0,0.0],\"units\":\"m\"},\"height\":{\"value\":2.5,\"units\":\"m\"},\"inner_radius\":{\"value\":0.0,\"units\":\"m\"},\"outer_radius\":{\"value\":1.0,\"units\":\"m\"}}],\"ghost_entities\":[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"GhostSurface\",\"private_attribute_id\":null,\"name\":\"farfield\",\"private_attribute_full_name\":null,\"type_name\":\"GhostSphere\",\"center\":[0.2500000000000003,0.0,1.2478015079531168e-9],\"max_radius\":106.00174010911132},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"GhostCircularPlane\",\"private_attribute_id\":null,\"name\":\"symmetric-1\",\"private_attribute_full_name\":null,\"center\":[0.2500000000000003,-1.0600174010911132,1.2478015079531168e-9],\"max_radius\":2.1200348021822264,\"normal_axis\":[0,1,0]},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"GhostCircularPlane\",\"private_attribute_id\":null,\"name\":\"symmetric-2\",\"private_attribute_full_name\":null,\"center\":[0.2500000000000003,1.0600174010911132,1.2478015079531168e-9],\"max_radius\":2.1200348021822264,\"normal_axis\":[0,1,0]}],\"type_name\":\"GeometryEntityInfo\",\"face_ids\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"],\"face_attribute_names\":[\"faceName\",\"groupName\",\"faceId\"],\"grouped_faces\":[[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"wing\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceName\",\"private_attribute_sub_components\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"]}],[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"wing\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"groupName\",\"private_attribute_sub_components\":[\"body0001_face0001\",\"body0001_face0002\",\"body0001_face0003\",\"body0001_face0004\",\"body0001_face0005\"]}],[{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"body0001_face0001\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceId\",\"private_attribute_sub_components\":[\"body0001_face0001\"]},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"body0001_face0002\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceId\",\"private_attribute_sub_components\":[\"body0001_face0002\"]},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"body0001_face0003\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceId\",\"private_attribute_sub_components\":[\"body0001_face0003\"]},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"body0001_face0004\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceId\",\"private_attribute_sub_components\":[\"body0001_face0004\"]},{\"private_attribute_registry_bucket_name\":\"SurfaceEntityType\",\"private_attribute_entity_type_name\":\"Surface\",\"private_attribute_id\":null,\"name\":\"body0001_face0005\",\"private_attribute_full_name\":null,\"private_attribute_is_interface\":null,\"private_attribute_tag_key\":\"faceId\",\"private_attribute_sub_components\":[\"body0001_face0005\"]}]],\"edge_ids\":[\"body0001_edge0001\",\"body0001_edge0002\",\"body0001_edge0003\",\"body0001_edge0004\",\"body0001_edge0005\",\"body0001_edge0006\",\"body0001_edge0007\",\"body0001_edge0008\",\"body0001_edge0010\",\"body0001_edge0011\",\"body0001_edge0013\"],\"edge_attribute_names\":[\"edgeName\",\"edgeId\"],\"grouped_edges\":[[{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"trailingEdge\",\"private_attribute_tag_key\":\"edgeName\",\"private_attribute_sub_components\":[\"body0001_edge0001\",\"body0001_edge0006\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"leadingEdge\",\"private_attribute_tag_key\":\"edgeName\",\"private_attribute_sub_components\":[\"body0001_edge0003\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0002\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0002\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0004\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0004\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0005\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0005\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0007\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0007\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0008\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0008\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0010\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0010\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0011\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0011\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0013\",\"private_attribute_tag_key\":\"__standalone__\",\"private_attribute_sub_components\":[\"body0001_edge0013\"]}],[{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0001\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0001\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0002\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0002\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0003\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0003\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0004\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0004\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0005\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0005\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0006\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0006\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0007\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0007\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0008\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0008\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0010\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0010\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0011\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0011\"]},{\"private_attribute_registry_bucket_name\":\"EdgeEntityType\",\"private_attribute_entity_type_name\":\"Edge\",\"private_attribute_id\":null,\"name\":\"body0001_edge0013\",\"private_attribute_tag_key\":\"edgeId\",\"private_attribute_sub_components\":[\"body0001_edge0013\"]}]],\"face_group_tag\":\"faceName\",\"edge_group_tag\":\"edgeName\"}}}"
}
-}
\ No newline at end of file
+}
diff --git a/tests/ref/simulation/service_init_geometry.json b/tests/ref/simulation/service_init_geometry.json
index c290925f8..5a708783d 100644
--- a/tests/ref/simulation/service_init_geometry.json
+++ b/tests/ref/simulation/service_init_geometry.json
@@ -1,9 +1,10 @@
{
- "version": "25.7.4b0",
+ "version": "25.8.0b3",
"unit_system": {
"name": "SI"
},
"meshing": {
+ "type_name": "MeshingParams",
"refinement_factor": 1.0,
"gap_treatment_strength": 0.0,
"defaults": {
diff --git a/tests/ref/simulation/service_init_surface_mesh.json b/tests/ref/simulation/service_init_surface_mesh.json
index 0ac4df709..9dcabb74b 100644
--- a/tests/ref/simulation/service_init_surface_mesh.json
+++ b/tests/ref/simulation/service_init_surface_mesh.json
@@ -1,9 +1,10 @@
{
- "version": "25.7.4b0",
+ "version": "25.8.0b3",
"unit_system": {
"name": "SI"
},
"meshing": {
+ "type_name": "MeshingParams",
"refinement_factor": 1.0,
"gap_treatment_strength": 0.0,
"defaults": {
@@ -306,4 +307,4 @@
"use_inhouse_mesher": false,
"use_geometry_AI": false
}
-}
\ No newline at end of file
+}
diff --git a/tests/ref/simulation/service_init_volume_mesh.json b/tests/ref/simulation/service_init_volume_mesh.json
index 8bb39d0d1..0951f2baf 100644
--- a/tests/ref/simulation/service_init_volume_mesh.json
+++ b/tests/ref/simulation/service_init_volume_mesh.json
@@ -1,5 +1,5 @@
{
- "version": "25.7.4b0",
+ "version": "25.8.0b3",
"unit_system": {
"name": "SI"
},
diff --git a/tests/simulation/asset/test_geometry.py b/tests/simulation/asset/test_geometry.py
index aba220e4d..a9e535197 100644
--- a/tests/simulation/asset/test_geometry.py
+++ b/tests/simulation/asset/test_geometry.py
@@ -7,7 +7,9 @@
from flow360 import exceptions as ex
from flow360.component.geometry import Geometry, GeometryMeta
from flow360.component.resource_base import local_metadata_builder
+from flow360.component.simulation.primitives import SnappyBody, Surface
from flow360.examples import Cylinder3D
+from flow360.exceptions import Flow360ValueError
assertions = unittest.TestCase("__init__")
@@ -23,6 +25,29 @@ def change_test_dir(request, monkeypatch):
monkeypatch.chdir(request.fspath.dirname)
+@pytest.fixture
+def stl_geo_meta():
+ geo_meta = {
+ "id": "geo-b2ca24af-f60d-4fb3-8120-c653f3e65be6",
+ "name": "stl_mixed_convention",
+ "s3_path": "s3://flow360meshes-v1/users/user-id",
+ }
+
+ geometry = Geometry.from_local_storage(
+ geometry_id=geo_meta["id"],
+ local_storage_path=os.path.join("../../data", geo_meta["id"]),
+ meta_data=GeometryMeta(
+ **local_metadata_builder(
+ id=geo_meta["id"],
+ name=geo_meta["name"],
+ cloud_path_prefix=geo_meta["s3_path"].rsplit("/", 1)[0],
+ status="processed",
+ )
+ ),
+ )
+ return geometry
+
+
def test_draft_geometry_from_file():
with pytest.raises(
ex.Flow360FileError,
@@ -296,3 +321,54 @@ def test_geometry_rename_body_groups():
match=(f"No entity found in registry with given name/naming pattern: 'newAirplane_0002'."),
):
assert geometry["newAirplane_0002"]
+
+
+def test_geometry_group_for_snappy(stl_geo_meta):
+ geo: Geometry = stl_geo_meta
+
+ with pytest.raises(Flow360ValueError):
+ geo.snappy_bodies
+
+ geo.group_faces_for_snappy()
+
+ # body with one region
+ assert isinstance(geo.snappy_bodies["rr-wh-rim-lhs"], SnappyBody)
+ assert len(geo.snappy_bodies["rr-wh-rim-lhs"]["*"]) == 1
+ assert isinstance(geo.snappy_bodies["rr-wh-rim-lhs"]["*"][0], Surface)
+ assert geo.snappy_bodies["rr-wh-rim-lhs"]["*"][0].name == "rr-wh-rim-lhs"
+
+ # body with more regions
+ assert all([isinstance(region, Surface) for region in geo.snappy_bodies["tunnel"]["*"]])
+ assert len(geo.snappy_bodies["tunnel"]["*"]) == 5
+
+ # registry wildcard
+ assert len(geo["uf*"]) == 2
+ assert len(geo["velocity*"]) == 10
+ assert all([isinstance(region, Surface) for region in geo["velocity*"]])
+ assert all([isinstance(region, SnappyBody) for region in geo.snappy_bodies["velocity*"]])
+
+ # double indexing with wildcard
+ assert len(geo.snappy_bodies["*nn*"]["*"]) == 6
+
+
+def test_snappy_grouping_not_found_messages(stl_geo_meta):
+ geo: Geometry = stl_geo_meta
+
+ geo.group_faces_for_snappy()
+
+ with pytest.raises(
+ ValueError,
+ match=(f"No entity found in registry with given name/naming pattern: 'dummy'."),
+ ):
+ assert geo.snappy_bodies["dummy"]
+
+ with pytest.raises(
+ ValueError,
+ match=(
+ f"No entity found in registry for parent entities: body-inner-nlyr, tunnel with given name/naming pattern: 'dummy'."
+ ),
+ ):
+ assert geo.snappy_bodies["*nn*"]["dummy"]
+
+ with pytest.raises(KeyError):
+ assert geo.snappy_bodies["body-nose"]["dummy*"]
diff --git a/tests/simulation/converter/test_monitor_flow360_converter.py b/tests/simulation/converter/test_monitor_flow360_converter.py
index 7c2a99d2a..d87f01f21 100644
--- a/tests/simulation/converter/test_monitor_flow360_converter.py
+++ b/tests/simulation/converter/test_monitor_flow360_converter.py
@@ -45,7 +45,7 @@ def test_flow360_monitor_convert():
)
with open("./ref/ref_monitor.json", mode="r") as fp:
ref_dict = json.load(fp=fp)
- assert compare_values(params_dict, ref_dict, ignore_keys=["private_attribute_id"])
+ assert compare_values(params_dict, ref_dict, ignore_keys=["private_attribute_id", "version"])
with pytest.raises(
ValueError,
diff --git a/tests/simulation/params/data/surface_mesh/simulation.json b/tests/simulation/params/data/surface_mesh/simulation.json
index 01109d4de..804578ac9 100644
--- a/tests/simulation/params/data/surface_mesh/simulation.json
+++ b/tests/simulation/params/data/surface_mesh/simulation.json
@@ -504,4 +504,4 @@
]
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/simulation/params/meshing_validation/test_meshing_param_validation.py b/tests/simulation/params/meshing_validation/test_meshing_param_validation.py
index 5ac5f3b37..c292bf489 100644
--- a/tests/simulation/params/meshing_validation/test_meshing_param_validation.py
+++ b/tests/simulation/params/meshing_validation/test_meshing_param_validation.py
@@ -1,22 +1,168 @@
import pydantic as pd
import pytest
-from flow360.component.simulation.meshing_param.params import MeshingParams
+from flow360 import u
+from flow360.component.simulation.meshing_param.meshing_specs import (
+ BetaVolumeMeshingDefaults,
+ OctreeSpacing,
+ SnappySurfaceMeshingDefaults,
+)
+from flow360.component.simulation.meshing_param.params import (
+ BetaVolumeMeshingParams,
+ MeshingParams,
+ ModularMeshingWorkflow,
+ SnappySurfaceMeshingParams,
+)
+from flow360.component.simulation.meshing_param.surface_mesh_refinements import (
+ SnappyBodyRefinement,
+)
from flow360.component.simulation.meshing_param.volume_params import (
AutomatedFarfield,
AxisymmetricRefinement,
- RotationCylinder,
+ RotationVolume,
+ StructuredBoxRefinement,
UniformRefinement,
+ UserDefinedFarfield,
+)
+from flow360.component.simulation.primitives import (
+ AxisymmetricBody,
+ Box,
+ Cylinder,
+ SeedpointZone,
+ SnappyBody,
+ Surface,
)
-from flow360.component.simulation.primitives import Cylinder, Surface
from flow360.component.simulation.simulation_params import SimulationParams
-from flow360.component.simulation.unit_system import CGS_unit_system
+from flow360.component.simulation.unit_system import CGS_unit_system, SI_unit_system
+from flow360.component.simulation.validation.validation_context import (
+ SURFACE_MESH,
+ VOLUME_MESH,
+ ParamsValidationInfo,
+ ValidationContext,
+)
+
+non_beta_mesher_context = ParamsValidationInfo({}, [])
+non_beta_mesher_context.is_beta_mesher = False
+
+beta_mesher_context = ParamsValidationInfo({}, [])
+beta_mesher_context.is_beta_mesher = True
+beta_mesher_context.project_length_unit = "mm"
+
+
+def test_structured_box_only_in_beta_mesher():
+ # raises when beta mesher is off
+ with pytest.raises(
+ pd.ValidationError,
+ match=r"`StructuredBoxRefinement` is only supported with the beta mesher.",
+ ):
+ with ValidationContext(VOLUME_MESH, non_beta_mesher_context):
+ with CGS_unit_system:
+ porous_medium = Box.from_principal_axes(
+ name="porousRegion",
+ center=(0, 1, 1),
+ size=(1, 2, 1),
+ axes=((2, 2, 0), (-2, 2, 0)),
+ )
+ _ = StructuredBoxRefinement(
+ entities=[porous_medium],
+ spacing_axis1=10,
+ spacing_axis2=10,
+ spacing_normal=10,
+ )
+
+ # does not raise with beta mesher on
+ with ValidationContext(VOLUME_MESH, beta_mesher_context):
+ with CGS_unit_system:
+ porous_medium = Box.from_principal_axes(
+ name="porousRegion",
+ center=(0, 1, 1),
+ size=(1, 2, 1),
+ axes=((2, 2, 0), (-2, 2, 0)),
+ )
+ _ = StructuredBoxRefinement(
+ entities=[porous_medium],
+ spacing_axis1=10,
+ spacing_axis2=10,
+ spacing_normal=10,
+ )
+
+
+def test_no_reuse_box_in_refinements():
+ with pytest.raises(
+ pd.ValidationError,
+ match=r"Using Volume entity `box-reused` in `StructuredBoxRefinement`, `UniformRefinement` at the same time is not allowed.",
+ ):
+ with ValidationContext(VOLUME_MESH, beta_mesher_context):
+ with CGS_unit_system:
+ porous_medium = Box.from_principal_axes(
+ name="box-reused",
+ center=(0, 1, 1),
+ size=(1, 2, 1),
+ axes=((2, 2, 0), (-2, 2, 0)),
+ )
+ structured_box_refine = StructuredBoxRefinement(
+ entities=[porous_medium],
+ spacing_axis1=10,
+ spacing_axis2=10,
+ spacing_normal=10,
+ )
+ uniform_refine = UniformRefinement(entities=[porous_medium], spacing=10)
+
+ SimulationParams(
+ meshing=MeshingParams(
+ refinements=[uniform_refine, structured_box_refine],
+ )
+ )
+
+
+def test_disable_invalid_axisymmetric_body_construction():
+ import re
+
+ with pytest.raises(
+ pd.ValidationError,
+ match=re.escape("Value error, arg '(-1, 1, 3)' needs to be a collection of 2 values"),
+ ):
+ with CGS_unit_system:
+ cylinder_1 = AxisymmetricBody(
+ name="1",
+ axis=(0, 0, 1),
+ center=(0, 5, 0),
+ profile_curve=[(-1, 0), (-1, 1, 3), (1, 1), (1, 0)],
+ )
+ with pytest.raises(
+ pd.ValidationError,
+ match=re.escape(
+ "Expect first profile sample to be (Axial, 0.0). Found invalid point: [-1. 1.] cm."
+ ),
+ ):
+ with CGS_unit_system:
+ cylinder_1 = AxisymmetricBody(
+ name="1",
+ axis=(0, 0, 1),
+ center=(0, 5, 0),
+ profile_curve=[(-1, 1), (1, 2)],
+ )
-def test_disable_multiple_cylinder_in_one_ratataion_cylinder():
with pytest.raises(
pd.ValidationError,
- match="Only single instance is allowed in entities for each RotationCylinder.",
+ match=re.escape(
+ "Expect last profile sample to be (Axial, 0.0). Found invalid point: [1. 1.] cm."
+ ),
+ ):
+ with CGS_unit_system:
+ cylinder_1 = AxisymmetricBody(
+ name="1",
+ axis=(0, 0, 1),
+ center=(0, 5, 0),
+ profile_curve=[(-1, 0), (-1, 1), (1, 1)],
+ )
+
+
+def test_disable_multiple_cylinder_in_one_rotation_volume():
+ with pytest.raises(
+ pd.ValidationError,
+ match="Only single instance is allowed in entities for each `RotationVolume`.",
):
with CGS_unit_system:
cylinder_1 = Cylinder(
@@ -36,7 +182,7 @@ def test_disable_multiple_cylinder_in_one_ratataion_cylinder():
SimulationParams(
meshing=MeshingParams(
volume_zones=[
- RotationCylinder(
+ RotationVolume(
entities=[cylinder_1, cylinder_2],
spacing_axial=20,
spacing_radial=0.2,
@@ -49,27 +195,30 @@ def test_disable_multiple_cylinder_in_one_ratataion_cylinder():
],
)
)
-
-
-def test_limit_cylinder_entity_name_length_in_rotation_cylinder():
with pytest.raises(
pd.ValidationError,
- match=r"The name \(very_long_cylinder_name\) of `Cylinder` entity in `RotationCylinder`"
- + " exceeds 18 characters limit.",
+ match="Only single instance is allowed in entities for each `RotationVolume`.",
):
with CGS_unit_system:
- cylinder = Cylinder(
- name="very_long_cylinder_name",
+ cylinder_1 = Cylinder(
+ name="1",
outer_radius=12,
height=2,
axis=(0, 1, 0),
center=(0, 5, 0),
)
+ cylinder_2 = Cylinder(
+ name="2",
+ outer_radius=2,
+ height=2,
+ axis=(0, 1, 0),
+ center=(0, 5, 0),
+ )
SimulationParams(
- meshing=MeshingParams(
- volume_zones=[
- RotationCylinder(
- entities=[cylinder],
+ meshing=ModularMeshingWorkflow(
+ zones=[
+ RotationVolume(
+ entities=[cylinder_1, cylinder_2],
spacing_axial=20,
spacing_radial=0.2,
spacing_circumferential=20,
@@ -83,10 +232,103 @@ def test_limit_cylinder_entity_name_length_in_rotation_cylinder():
)
+def test_limit_cylinder_entity_name_length_in_rotation_volume():
+ # raises when beta mesher is off
+ with pytest.raises(
+ pd.ValidationError,
+ match=r"The name \(very_long_cylinder_name\) of `Cylinder` entity in `RotationVolume`"
+ + " exceeds 18 characters limit.",
+ ):
+ with ValidationContext(VOLUME_MESH, non_beta_mesher_context):
+ with CGS_unit_system:
+ cylinder = Cylinder(
+ name="very_long_cylinder_name",
+ outer_radius=12,
+ height=2,
+ axis=(0, 1, 0),
+ center=(0, 5, 0),
+ )
+ _ = RotationVolume(
+ entities=[cylinder],
+ spacing_axial=20,
+ spacing_radial=0.2,
+ spacing_circumferential=20,
+ enclosed_entities=[
+ Surface(name="hub"),
+ ],
+ )
+
+ # does not raise with beta mesher on
+ with ValidationContext(VOLUME_MESH, beta_mesher_context):
+ with CGS_unit_system:
+ cylinder2 = Cylinder(
+ name="very_long_cylinder_name",
+ outer_radius=12,
+ height=2,
+ axis=(0, 1, 0),
+ center=(0, 5, 0),
+ )
+ _ = RotationVolume(
+ entities=[cylinder2],
+ spacing_axial=20,
+ spacing_radial=0.2,
+ spacing_circumferential=20,
+ enclosed_entities=[
+ Surface(name="hub"),
+ ],
+ )
+
+
+def test_limit_axisymmetric_body_in_rotation_volume():
+ # raises when beta mesher is off
+ with pytest.raises(
+ pd.ValidationError,
+ match=r"`AxisymmetricBody` entity for `RotationVolume` is only supported with the beta mesher.",
+ ):
+ with ValidationContext(VOLUME_MESH, non_beta_mesher_context):
+ with CGS_unit_system:
+ cylinder_1 = AxisymmetricBody(
+ name="1",
+ axis=(0, 0, 1),
+ center=(0, 5, 0),
+ profile_curve=[(-1, 0), (-1, 1), (1, 1), (1, 0)],
+ )
+
+ _ = RotationVolume(
+ entities=[cylinder_1],
+ spacing_axial=20,
+ spacing_radial=0.2,
+ spacing_circumferential=20,
+ enclosed_entities=[
+ Surface(name="hub"),
+ ],
+ )
+
+ # does not raise with beta mesher on
+ with ValidationContext(VOLUME_MESH, beta_mesher_context):
+ with CGS_unit_system:
+ cylinder_2 = AxisymmetricBody(
+ name="1",
+ axis=(0, 0, 1),
+ center=(0, 5, 0),
+ profile_curve=[(-1, 0), (-1, 1), (1, 1), (1, 0)],
+ )
+
+ _ = RotationVolume(
+ entities=[cylinder_2],
+ spacing_axial=20,
+ spacing_radial=0.2,
+ spacing_circumferential=20,
+ enclosed_entities=[
+ Surface(name="hub"),
+ ],
+ )
+
+
def test_reuse_of_same_cylinder():
with pytest.raises(
pd.ValidationError,
- match=r"Using Volume entity `I am reused` in `AxisymmetricRefinement`, `RotationCylinder` at the same time is not allowed.",
+ match=r"Using Volume entity `I am reused` in `AxisymmetricRefinement`, `RotationVolume` at the same time is not allowed.",
):
with CGS_unit_system:
cylinder = Cylinder(
@@ -99,7 +341,7 @@ def test_reuse_of_same_cylinder():
SimulationParams(
meshing=MeshingParams(
volume_zones=[
- RotationCylinder(
+ RotationVolume(
entities=[cylinder],
spacing_axial=20,
spacing_radial=0.2,
@@ -121,6 +363,46 @@ def test_reuse_of_same_cylinder():
)
)
+ with pytest.raises(
+ pd.ValidationError,
+ match=r"Using Volume entity `I am reused` in `AxisymmetricRefinement`, `RotationVolume` at the same time is not allowed.",
+ ):
+ with CGS_unit_system:
+ cylinder = Cylinder(
+ name="I am reused",
+ outer_radius=1,
+ height=12,
+ axis=(0, 1, 0),
+ center=(0, 5, 0),
+ )
+ SimulationParams(
+ meshing=ModularMeshingWorkflow(
+ volume_meshing=BetaVolumeMeshingParams(
+ refinements=[
+ AxisymmetricRefinement(
+ entities=[cylinder],
+ spacing_axial=0.1,
+ spacing_radial=0.2,
+ spacing_circumferential=0.3,
+ )
+ ],
+ defaults=BetaVolumeMeshingDefaults(boundary_layer_first_layer_thickness=1),
+ ),
+ zones=[
+ RotationVolume(
+ entities=[cylinder],
+ spacing_axial=20,
+ spacing_radial=0.2,
+ spacing_circumferential=20,
+ enclosed_entities=[
+ Surface(name="hub"),
+ ],
+ ),
+ AutomatedFarfield(),
+ ],
+ )
+ )
+
with CGS_unit_system:
cylinder = Cylinder(
name="Okay to reuse",
@@ -132,7 +414,7 @@ def test_reuse_of_same_cylinder():
SimulationParams(
meshing=MeshingParams(
volume_zones=[
- RotationCylinder(
+ RotationVolume(
entities=[cylinder],
spacing_axial=20,
spacing_radial=0.2,
@@ -152,6 +434,40 @@ def test_reuse_of_same_cylinder():
)
)
+ with CGS_unit_system:
+ cylinder = Cylinder(
+ name="Okay to reuse",
+ outer_radius=1,
+ height=12,
+ axis=(0, 1, 0),
+ center=(0, 5, 0),
+ )
+ SimulationParams(
+ meshing=ModularMeshingWorkflow(
+ volume_meshing=BetaVolumeMeshingParams(
+ refinements=[
+ UniformRefinement(
+ entities=[cylinder],
+ spacing=0.1,
+ )
+ ],
+ defaults=BetaVolumeMeshingDefaults(boundary_layer_first_layer_thickness=1),
+ ),
+ zones=[
+ RotationVolume(
+ entities=[cylinder],
+ spacing_axial=20,
+ spacing_radial=0.2,
+ spacing_circumferential=20,
+ enclosed_entities=[
+ Surface(name="hub"),
+ ],
+ ),
+ AutomatedFarfield(),
+ ],
+ )
+ )
+
with pytest.raises(
pd.ValidationError,
match=r"Using Volume entity `I am reused` in `AxisymmetricRefinement`, `UniformRefinement` at the same time is not allowed.",
@@ -178,6 +494,36 @@ def test_reuse_of_same_cylinder():
)
)
+ with pytest.raises(
+ pd.ValidationError,
+ match=r"Using Volume entity `I am reused` in `AxisymmetricRefinement`, `UniformRefinement` at the same time is not allowed.",
+ ):
+ with CGS_unit_system:
+ cylinder = Cylinder(
+ name="I am reused",
+ outer_radius=1,
+ height=12,
+ axis=(0, 1, 0),
+ center=(0, 5, 0),
+ )
+ SimulationParams(
+ meshing=ModularMeshingWorkflow(
+ volume_meshing=BetaVolumeMeshingParams(
+ refinements=[
+ UniformRefinement(entities=[cylinder], spacing=0.1),
+ AxisymmetricRefinement(
+ entities=[cylinder],
+ spacing_axial=0.1,
+ spacing_radial=0.1,
+ spacing_circumferential=0.1,
+ ),
+ ],
+ defaults=BetaVolumeMeshingDefaults(boundary_layer_first_layer_thickness=1),
+ ),
+ zones=[AutomatedFarfield()],
+ )
+ )
+
with pytest.raises(
pd.ValidationError,
match=r" Volume entity `I am reused` is used multiple times in `UniformRefinement`.",
@@ -198,3 +544,199 @@ def test_reuse_of_same_cylinder():
],
)
)
+
+ with pytest.raises(
+ pd.ValidationError,
+ match=r" Volume entity `I am reused` is used multiple times in `UniformRefinement`.",
+ ):
+ with CGS_unit_system:
+ cylinder = Cylinder(
+ name="I am reused",
+ outer_radius=1,
+ height=12,
+ axis=(0, 1, 0),
+ center=(0, 5, 0),
+ )
+ SimulationParams(
+ meshing=ModularMeshingWorkflow(
+ volume_meshing=BetaVolumeMeshingParams(
+ refinements=[
+ UniformRefinement(entities=[cylinder], spacing=0.1),
+ UniformRefinement(entities=[cylinder], spacing=0.2),
+ ],
+ defaults=BetaVolumeMeshingDefaults(boundary_layer_first_layer_thickness=1),
+ ),
+ zones=[AutomatedFarfield()],
+ )
+ )
+
+
+def test_require_mesh_zones():
+ with SI_unit_system:
+ ModularMeshingWorkflow(
+ surface_meshing=SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=1 * u.mm, max_spacing=5 * u.mm, gap_resolution=0.001 * u.mm
+ ),
+ ),
+ zones=[AutomatedFarfield()],
+ )
+
+ with SI_unit_system:
+ ModularMeshingWorkflow(
+ surface_meshing=SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=1 * u.mm, max_spacing=5 * u.mm, gap_resolution=0.01 * u.mm
+ ),
+ ),
+ zones=[SeedpointZone(name="fluid", point_in_mesh=(0, 0, 0) * u.mm)],
+ )
+
+ with pytest.raises(ValueError):
+ with SI_unit_system:
+ ModularMeshingWorkflow(
+ surface_meshing=SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=1 * u.mm, max_spacing=5 * u.mm, gap_resolution=0.01 * u.mm
+ )
+ ),
+ zones=[UserDefinedFarfield()],
+ )
+
+
+def test_bad_refinements():
+ with pytest.raises(ValueError):
+ surface_meshing = SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=1 * u.mm, max_spacing=5 * u.mm, gap_resolution=0.01 * u.mm
+ ),
+ refinements=[
+ SnappyBodyRefinement(
+ min_spacing=6 * u.mm, bodies=[SnappyBody(name="bbb", surfaces=[])]
+ )
+ ],
+ )
+
+ with pytest.raises(ValueError):
+ surface_meshing = SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=1 * u.mm, max_spacing=5 * u.mm, gap_resolution=0.01 * u.mm
+ ),
+ refinements=[
+ SnappyBodyRefinement(
+ max_spacing=0.5 * u.mm, bodies=[SnappyBody(name="bbb", surfaces=[])]
+ )
+ ],
+ )
+
+
+def test_box_entity_enclosed_only_in_beta_mesher():
+ # raises when beta mesher is off
+ with pytest.raises(
+ pd.ValidationError,
+ match=r"`Box` entity in `RotationVolume.enclosed_entities` is only supported with the beta mesher.",
+ ):
+ with ValidationContext(VOLUME_MESH, non_beta_mesher_context):
+ with CGS_unit_system:
+ cylinder = Cylinder(
+ name="cylinder",
+ outer_radius=1,
+ height=12,
+ axis=(0, 1, 0),
+ center=(0, 5, 0),
+ )
+ box_entity = Box.from_principal_axes(
+ name="box",
+ center=(0, 1, 1),
+ size=(1, 2, 1),
+ axes=((2, 2, 0), (-2, 2, 0)),
+ )
+ _ = RotationVolume(
+ entities=[cylinder],
+ spacing_axial=20,
+ spacing_radial=0.2,
+ spacing_circumferential=20,
+ enclosed_entities=[box_entity],
+ )
+
+ # does not raise with beta mesher on
+ with ValidationContext(VOLUME_MESH, beta_mesher_context):
+ with CGS_unit_system:
+ cylinder = Cylinder(
+ name="cylinder",
+ outer_radius=1,
+ height=12,
+ axis=(0, 1, 0),
+ center=(0, 5, 0),
+ )
+ box_entity = Box.from_principal_axes(
+ name="box",
+ center=(0, 1, 1),
+ size=(1, 2, 1),
+ axes=((2, 2, 0), (-2, 2, 0)),
+ )
+ _ = RotationVolume(
+ entities=[cylinder],
+ spacing_axial=20,
+ spacing_radial=0.2,
+ spacing_circumferential=20,
+ enclosed_entities=[box_entity],
+ )
+
+
+def test_octree_spacing():
+ spacing = OctreeSpacing(base_spacing=2 * u.mm)
+
+ assert spacing[0] == 2 * u.mm
+ assert spacing[3] == 2 * u.mm * (2**-3)
+ assert spacing[-4] == 2 * u.mm * (2**4)
+ assert spacing[1] == 2 * u.mm * (2**-1)
+
+ with pytest.raises(pd.ValidationError):
+ _ = spacing[0.2]
+
+ assert spacing.to_level(2 * u.mm) == (0, True)
+ assert spacing.to_level(4 * u.mm) == (-1, True)
+ assert spacing.to_level(0.5 * u.mm) == (2, True)
+ assert spacing.to_level(3.9993 * u.mm) == (0, False)
+ assert spacing.to_level(3.9999999999993 * u.mm) == (-1, True)
+
+
+def test_set_default_base_spacing():
+ surface_meshing = SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=1 * u.mm, max_spacing=2 * u.mm, gap_resolution=1 * u.mm
+ )
+ )
+
+ assert surface_meshing.base_spacing is None
+
+ with ValidationContext(SURFACE_MESH, beta_mesher_context):
+ surface_meshing = SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=1 * u.mm, max_spacing=2 * u.mm, gap_resolution=1 * u.mm
+ )
+ )
+
+ assert surface_meshing.base_spacing.base_spacing == 1 * u.mm
+ assert surface_meshing.base_spacing[2] == 0.25 * u.mm
+ assert surface_meshing.base_spacing.to_level(2 * u.mm) == (-1, True)
+
+
+def test_set_spacing_with_value():
+ surface_meshing = SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=1 * u.mm, max_spacing=2 * u.mm, gap_resolution=1 * u.mm
+ ),
+ base_spacing=3 * u.mm,
+ )
+
+ assert surface_meshing.base_spacing.base_spacing == 3 * u.mm
+
+ with pytest.raises(pd.ValidationError):
+ surface_meshing = SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=1 * u.mm, max_spacing=2 * u.mm, gap_resolution=1 * u.mm
+ ),
+ base_spacing=-3 * u.mm,
+ )
diff --git a/tests/simulation/params/meshing_validation/test_refinements_validation.py b/tests/simulation/params/meshing_validation/test_refinements_validation.py
new file mode 100644
index 000000000..41a23b8c4
--- /dev/null
+++ b/tests/simulation/params/meshing_validation/test_refinements_validation.py
@@ -0,0 +1,134 @@
+import re
+
+import pydantic as pd
+import pytest
+
+import flow360.component.simulation.units as u
+from flow360.component.simulation.meshing_param.params import (
+ SnappySurfaceMeshingDefaults,
+ SnappySurfaceMeshingParams,
+)
+from flow360.component.simulation.meshing_param.surface_mesh_refinements import (
+ SnappyRegionRefinement,
+ SnappySurfaceEdgeRefinement,
+)
+from flow360.component.simulation.meshing_param.volume_params import UniformRefinement
+from flow360.component.simulation.primitives import Box, Cylinder, Surface
+from flow360.component.simulation.unit_system import SI_unit_system
+
+
+def test_snappy_refinements_validators():
+ message = "Minimum spacing must be lower than maximum spacing."
+ with SI_unit_system, pytest.raises(ValueError, match=re.escape(message)):
+ SnappyRegionRefinement(
+ min_spacing=4.3 * u.mm, max_spacing=2.1 * u.mm, regions=[Surface(name="test")]
+ )
+
+ message = "UniformRefinement for snappy accepts only Boxes with axes aligned with the global coordinate system (angle_of_rotation=0)."
+ with SI_unit_system, pytest.raises(ValueError, match=re.escape(message)) as err:
+ SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=3 * u.mm, max_spacing=10 * u.mm, gap_resolution=0.1 * u.mm
+ ),
+ refinements=[
+ UniformRefinement(
+ name="unif",
+ spacing=6 * u.mm,
+ entities=[
+ Box(
+ center=[2, 3, 4] * u.m,
+ size=[5, 6, 7] * u.m,
+ axis_of_rotation=[1, 3, 4],
+ angle_of_rotation=5 * u.deg,
+ name="box",
+ )
+ ],
+ )
+ ],
+ )
+
+ SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=3 * u.mm, max_spacing=10 * u.mm, gap_resolution=0.1 * u.mm
+ ),
+ refinements=[
+ UniformRefinement(
+ name="unif",
+ spacing=6 * u.mm,
+ entities=[
+ Box(
+ center=[2, 3, 4] * u.m,
+ size=[5, 6, 7] * u.m,
+ axis_of_rotation=[1, 3, 4],
+ angle_of_rotation=0 * u.deg,
+ name="box",
+ )
+ ],
+ )
+ ],
+ )
+
+ message = "UniformRefinement for snappy accepts only full cylinders (where inner_radius = 0)."
+ with SI_unit_system, pytest.raises(ValueError, match=re.escape(message)):
+ SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=3 * u.mm, max_spacing=10 * u.mm, gap_resolution=0.1 * u.mm
+ ),
+ refinements=[
+ UniformRefinement(
+ name="unif",
+ spacing=6 * u.mm,
+ entities=[
+ Cylinder(
+ name="cyl",
+ inner_radius=3 * u.mm,
+ outer_radius=7 * u.mm,
+ axis=[0, 0, 1],
+ center=[0, 0, 0] * u.m,
+ height=10 * u.mm,
+ )
+ ],
+ )
+ ],
+ )
+
+
+def test_snappy_edge_refinement_valdators():
+ with pytest.raises(ValueError):
+ SnappySurfaceEdgeRefinement(
+ spacing=2 * u.mm, distances=[5 * u.mm], regions=[Surface(name="test")]
+ )
+
+ with pytest.raises(ValueError):
+ SnappySurfaceEdgeRefinement(
+ spacing=[2 * u.mm, 3 * u.mm], distances=[5 * u.mm], regions=[Surface(name="test")]
+ )
+
+ with pytest.raises(ValueError):
+ SnappySurfaceEdgeRefinement(
+ spacing=2 * u.mm, distances=5 * u.mm, regions=[Surface(name="test")]
+ )
+
+ with pytest.raises(ValueError):
+ SnappySurfaceEdgeRefinement(spacing=[2 * u.mm], regions=[Surface(name="test")])
+
+ SnappySurfaceEdgeRefinement(
+ spacing=[2 * u.mm], distances=[5 * u.mm], regions=[Surface(name="test")]
+ )
+
+ SnappySurfaceEdgeRefinement(regions=[Surface(name="test")])
+
+ SnappySurfaceEdgeRefinement(spacing=2 * u.mm, regions=[Surface(name="test")])
+
+ SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=3 * u.mm, max_spacing=6 * u.mm, gap_resolution=0.1 * u.mm
+ ),
+ refinements=[
+ SnappySurfaceEdgeRefinement(
+ spacing=[2 * u.mm], distances=[5 * u.mm], regions=[Surface(name="test")]
+ ),
+ SnappySurfaceEdgeRefinement(spacing=2 * u.mm, regions=[Surface(name="test")]),
+ SnappySurfaceEdgeRefinement(regions=[Surface(name="test")]),
+ ],
+ )
diff --git a/tests/simulation/params/test_simulation_params.py b/tests/simulation/params/test_simulation_params.py
index 70d12122e..f69a519dd 100644
--- a/tests/simulation/params/test_simulation_params.py
+++ b/tests/simulation/params/test_simulation_params.py
@@ -16,6 +16,12 @@
from flow360.component.simulation.meshing_param.params import (
MeshingDefaults,
MeshingParams,
+ ModularMeshingWorkflow,
+ SnappySurfaceMeshingDefaults,
+ SnappySurfaceMeshingParams,
+)
+from flow360.component.simulation.meshing_param.surface_mesh_refinements import (
+ SnappySurfaceEdgeRefinement,
)
from flow360.component.simulation.meshing_param.volume_params import UniformRefinement
from flow360.component.simulation.migration.extra_operating_condition import (
@@ -53,6 +59,7 @@
Edge,
GenericVolume,
ReferenceGeometry,
+ SeedpointZone,
Surface,
)
from flow360.component.simulation.simulation_params import SimulationParams
@@ -210,6 +217,36 @@ def get_param_with_liquid_operating_condition():
return param
+@pytest.fixture()
+def get_param_with_list_of_lengths():
+ with SI_unit_system:
+ params = SimulationParams(
+ meshing=ModularMeshingWorkflow(
+ surface_meshing=SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=10 * u.mm, max_spacing=2 * u.m, gap_resolution=0.01 * u.m
+ ),
+ refinements=[
+ SnappySurfaceEdgeRefinement(
+ spacing=[1e-3, 8] * u.m,
+ distances=[0.4 * u.mm, 2 * u.m],
+ regions=[Surface(name="test")],
+ )
+ ],
+ ),
+ zones=[SeedpointZone(name="fluid", point_in_mesh=[1, 1, 1])],
+ ),
+ operating_condition=AerospaceCondition.from_mach(
+ mach=0.8,
+ alpha=30 * u.deg,
+ beta=20 * u.deg,
+ thermal_state=ThermalState(temperature=300 * u.K, density=1 * u.g / u.cm**3),
+ reference_mach=0.5,
+ ),
+ )
+ return params
+
+
@pytest.mark.usefixtures("array_equality_override")
def test_simulation_params_serialization(get_the_param):
to_file_from_file_test(get_the_param)
@@ -284,6 +321,26 @@ def test_simulation_params_unit_conversion(get_the_param):
)
+@pytest.mark.usefixtures("array_equality_override")
+def test_simulation_params_unit_conversion_with_list_of_lengths(get_param_with_list_of_lengths):
+ converted = get_param_with_list_of_lengths._preprocess(mesh_unit=10 * u.m)
+
+ assertions.assertAlmostEqual(converted.meshing.surface_meshing.defaults.min_spacing.value, 1e-3)
+ assertions.assertAlmostEqual(converted.meshing.surface_meshing.defaults.max_spacing, 0.2)
+
+ assertions.assertAlmostEqual(converted.meshing.surface_meshing.defaults.gap_resolution, 1e-3)
+
+ assertions.assertAlmostEqual(converted.meshing.surface_meshing.refinements[0].spacing[0], 1e-4)
+
+ assertions.assertAlmostEqual(converted.meshing.surface_meshing.refinements[0].spacing[1], 0.8)
+
+ assertions.assertAlmostEqual(
+ converted.meshing.surface_meshing.refinements[0].distances[0], 4e-5
+ )
+
+ assertions.assertAlmostEqual(converted.meshing.surface_meshing.refinements[0].distances[1], 0.2)
+
+
def test_standard_atmosphere():
# ref values from here: https://aerospaceweb.org/design/scripts/atmosphere/
# alt, temp_offset, temp, density, pressure, viscosity
diff --git a/tests/simulation/params/test_validators_params.py b/tests/simulation/params/test_validators_params.py
index bf6262ba6..56b268053 100644
--- a/tests/simulation/params/test_validators_params.py
+++ b/tests/simulation/params/test_validators_params.py
@@ -11,6 +11,10 @@
VolumeMeshEntityInfo,
)
from flow360.component.simulation.framework.param_utils import AssetCache
+from flow360.component.simulation.meshing_param.edge_params import (
+ HeightBasedRefinement,
+ SurfaceEdgeRefinement,
+)
from flow360.component.simulation.meshing_param.face_params import (
BoundaryLayer,
GeometryRefinement,
@@ -82,6 +86,7 @@
Box,
CustomVolume,
Cylinder,
+ Edge,
GenericVolume,
GhostCircularPlane,
GhostSphere,
@@ -101,6 +106,7 @@
from flow360.component.simulation.validation.validation_context import (
CASE,
VOLUME_MESH,
+ ParamsValidationInfo,
ValidationContext,
)
@@ -2060,6 +2066,39 @@ def test_geometry_AI_only_features():
)
+def test_geometry_AI_unsupported_features():
+ with SI_unit_system:
+ params = SimulationParams(
+ meshing=MeshingParams(
+ defaults=MeshingDefaults(
+ boundary_layer_first_layer_thickness=1e-4,
+ geometry_accuracy=1e-4 * u.m,
+ surface_max_aspect_ratio=20.0,
+ surface_max_adaptation_iterations=20,
+ ),
+ refinements=[
+ SurfaceEdgeRefinement(
+ edges=[Edge(name="edge0001")], method=HeightBasedRefinement(value=1e-4)
+ )
+ ],
+ ),
+ private_attribute_asset_cache=AssetCache(
+ use_inhouse_mesher=False, use_geometry_AI=True
+ ),
+ )
+ params, errors, _ = validate_model(
+ params_as_dict=params.model_dump(mode="json"),
+ validated_by=ValidationCalledBy.LOCAL,
+ root_item_type="Geometry",
+ validation_level="VolumeMesh",
+ )
+ assert len(errors) == 1
+ assert (
+ errors[0]["msg"]
+ == "Value error, SurfaceEdgeRefinement is not currently supported with geometry AI."
+ )
+
+
def test_redefined_user_defined_fields():
with SI_unit_system:
diff --git a/tests/simulation/ref/simulation_with_project_variables.json b/tests/simulation/ref/simulation_with_project_variables.json
index 5d88da7f3..cc2913bf3 100644
--- a/tests/simulation/ref/simulation_with_project_variables.json
+++ b/tests/simulation/ref/simulation_with_project_variables.json
@@ -1,5 +1,5 @@
{
- "version": "25.7.4b0",
+ "version": "25.8.0b3",
"unit_system": {
"name": "SI"
},
diff --git a/tests/simulation/service/data/simulation_missing_from_meshing.json b/tests/simulation/service/data/simulation_missing_from_meshing.json
new file mode 100644
index 000000000..d1290e7b1
--- /dev/null
+++ b/tests/simulation/service/data/simulation_missing_from_meshing.json
@@ -0,0 +1,2055 @@
+{
+ "version": "25.6.6",
+ "unit_system": {
+ "name": "SI"
+ },
+ "meshing": {
+ "refinement_factor": 1.0,
+ "gap_treatment_strength": 0.0,
+ "defaults": {
+ "surface_edge_growth_rate": 1.2,
+ "boundary_layer_growth_rate": 1.2,
+ "boundary_layer_first_layer_thickness": {
+ "value": 0.01,
+ "units": "mm"
+ },
+ "planar_face_tolerance": 1e-6,
+ "surface_max_edge_length": {
+ "value": 0.1,
+ "units": "m"
+ },
+ "surface_max_aspect_ratio": 10.0,
+ "surface_max_adaptation_iterations": 50,
+ "curvature_resolution_angle": {
+ "value": 12.0,
+ "units": "degree"
+ }
+ },
+ "refinements": [],
+ "volume_zones": [
+ {
+ "type": "AutomatedFarfield",
+ "name": "Farfield",
+ "method": "auto"
+ }
+ ]
+ },
+ "reference_geometry": {
+ "moment_center": {
+ "value": [
+ 0.0,
+ 0.0,
+ 0.0
+ ],
+ "units": "m"
+ },
+ "moment_length": {
+ "value": [
+ 1.0,
+ 1.0,
+ 1.0
+ ],
+ "units": "m"
+ },
+ "area": {
+ "type_name": "number",
+ "value": 1.0,
+ "units": "m**2"
+ }
+ },
+ "operating_condition": {
+ "type_name": "AerospaceCondition",
+ "private_attribute_constructor": "default",
+ "private_attribute_input_cache": {
+ "alpha": {
+ "value": 10.0,
+ "units": "degree"
+ },
+ "beta": {
+ "value": 0.0,
+ "units": "degree"
+ },
+ "thermal_state": {
+ "type_name": "ThermalState",
+ "private_attribute_constructor": "default",
+ "private_attribute_input_cache": {},
+ "temperature": {
+ "value": 288.15,
+ "units": "K"
+ },
+ "density": {
+ "value": 1.225,
+ "units": "kg/m**3"
+ },
+ "material": {
+ "type": "air",
+ "name": "air",
+ "dynamic_viscosity": {
+ "reference_viscosity": {
+ "value": 0.00001716,
+ "units": "Pa*s"
+ },
+ "reference_temperature": {
+ "value": 273.15,
+ "units": "K"
+ },
+ "effective_temperature": {
+ "value": 110.4,
+ "units": "K"
+ }
+ }
+ }
+ }
+ },
+ "alpha": {
+ "value": 10.0,
+ "units": "degree"
+ },
+ "beta": {
+ "value": 0.0,
+ "units": "degree"
+ },
+ "velocity_magnitude": {
+ "type_name": "number",
+ "value": 100.0,
+ "units": "m/s"
+ },
+ "thermal_state": {
+ "type_name": "ThermalState",
+ "private_attribute_constructor": "default",
+ "private_attribute_input_cache": {},
+ "temperature": {
+ "value": 288.15,
+ "units": "K"
+ },
+ "density": {
+ "value": 1.225,
+ "units": "kg/m**3"
+ },
+ "material": {
+ "type": "air",
+ "name": "air",
+ "dynamic_viscosity": {
+ "reference_viscosity": {
+ "value": 0.00001716,
+ "units": "Pa*s"
+ },
+ "reference_temperature": {
+ "value": 273.15,
+ "units": "K"
+ },
+ "effective_temperature": {
+ "value": 110.4,
+ "units": "K"
+ }
+ }
+ }
+ }
+ },
+ "models": [
+ {
+ "type": "Wall",
+ "entities": {
+ "stored_entities": [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "leftWing",
+ "name": "leftWing",
+ "private_attribute_tag_key": "groupName",
+ "private_attribute_sub_components": [
+ "body00001_face00001",
+ "body00001_face00002",
+ "body00001_face00003",
+ "body00001_face00004"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 2.955272566880039,
+ -5.0416453591327475,
+ -0.08384024903838053
+ ],
+ [
+ 8.50047405808511,
+ -0.3554294842220984,
+ 0.15942913832893682
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fuselage",
+ "name": "fuselage",
+ "private_attribute_tag_key": "groupName",
+ "private_attribute_sub_components": [
+ "body00001_face00005",
+ "body00001_face00006",
+ "body00001_face00007",
+ "body00001_face00008",
+ "body00001_face00009",
+ "body00001_face00010"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 0.0014996389999999999,
+ -0.45749012619146684,
+ -0.46072854876470765
+ ],
+ [
+ 10.0000001,
+ 0.4574901276161142,
+ 0.46072854876470765
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rightWing",
+ "name": "rightWing",
+ "private_attribute_tag_key": "groupName",
+ "private_attribute_sub_components": [
+ "body00001_face00011",
+ "body00001_face00012",
+ "body00001_face00013",
+ "body00001_face00014"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 2.9552725668800384,
+ 0.35542948383180295,
+ -0.08384024068111959
+ ],
+ [
+ 8.50047405808511,
+ 5.0416453591327475,
+ 0.15942913897469208
+ ]
+ ]
+ }
+ }
+ ]
+ },
+ "name": "Wall",
+ "use_wall_function": false,
+ "heat_spec": {
+ "value": {
+ "value": 0.0,
+ "units": "W/m**2"
+ },
+ "type_name": "HeatFlux"
+ },
+ "roughness_height": {
+ "value": 0.0,
+ "units": "m"
+ }
+ },
+ {
+ "type": "Freestream",
+ "entities": {
+ "stored_entities": [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "GhostSphere",
+ "private_attribute_id": "farfield",
+ "name": "farfield",
+ "center": [
+ 0,
+ 0,
+ 0
+ ],
+ "max_radius": 504.16453591327473
+ }
+ ]
+ },
+ "name": "Freestream"
+ },
+ {
+ "material": {
+ "type": "air",
+ "name": "air",
+ "dynamic_viscosity": {
+ "reference_viscosity": {
+ "value": 0.00001716,
+ "units": "Pa*s"
+ },
+ "reference_temperature": {
+ "value": 273.15,
+ "units": "K"
+ },
+ "effective_temperature": {
+ "value": 110.4,
+ "units": "K"
+ }
+ }
+ },
+ "initial_condition": {
+ "type_name": "NavierStokesInitialCondition",
+ "rho": "rho",
+ "u": "u",
+ "v": "v",
+ "w": "w",
+ "p": "p"
+ },
+ "type": "Fluid",
+ "navier_stokes_solver": {
+ "absolute_tolerance": 1e-10,
+ "relative_tolerance": 0.0,
+ "order_of_accuracy": 2,
+ "equation_evaluation_frequency": 1,
+ "linear_solver": {
+ "max_iterations": 30
+ },
+ "CFL_multiplier": 1.0,
+ "kappa_MUSCL": -1.0,
+ "numerical_dissipation_factor": 1.0,
+ "limit_velocity": false,
+ "limit_pressure_density": false,
+ "type_name": "Compressible",
+ "low_mach_preconditioner": false,
+ "update_jacobian_frequency": 4,
+ "max_force_jac_update_physical_steps": 0
+ },
+ "turbulence_model_solver": {
+ "absolute_tolerance": 1e-8,
+ "relative_tolerance": 0.0,
+ "order_of_accuracy": 2,
+ "equation_evaluation_frequency": 4,
+ "linear_solver": {
+ "max_iterations": 20
+ },
+ "CFL_multiplier": 2.0,
+ "type_name": "SpalartAllmaras",
+ "reconstruction_gradient_limiter": 0.5,
+ "quadratic_constitutive_relation": false,
+ "modeling_constants": {
+ "type_name": "SpalartAllmarasConsts",
+ "C_DES": 0.72,
+ "C_d": 8.0,
+ "C_cb1": 0.1355,
+ "C_cb2": 0.622,
+ "C_sigma": 0.6666666666666666,
+ "C_v1": 7.1,
+ "C_vonKarman": 0.41,
+ "C_w2": 0.3,
+ "C_t3": 1.2,
+ "C_t4": 0.5,
+ "C_min_rd": 10.0
+ },
+ "update_jacobian_frequency": 4,
+ "max_force_jac_update_physical_steps": 0,
+ "rotation_correction": false
+ },
+ "transition_model_solver": {
+ "type_name": "None"
+ }
+ }
+ ],
+ "time_stepping": {
+ "type_name": "Steady",
+ "max_steps": 2000,
+ "CFL": {
+ "type": "adaptive",
+ "min": 0.1,
+ "max": 10000.0,
+ "max_relative_change": 1.0,
+ "convergence_limiting_factor": 0.25
+ }
+ },
+ "user_defined_fields": [],
+ "outputs": [
+ {
+ "output_fields": {
+ "items": [
+ "Cp",
+ "yPlus",
+ "Cf",
+ "CfVec"
+ ]
+ },
+ "frequency": -1,
+ "frequency_offset": 0,
+ "output_format": "paraview",
+ "name": "Surface output",
+ "entities": {
+ "stored_entities": [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "leftWing",
+ "name": "leftWing",
+ "private_attribute_tag_key": "groupName",
+ "private_attribute_sub_components": [
+ "body00001_face00001",
+ "body00001_face00002",
+ "body00001_face00003",
+ "body00001_face00004"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 2.955272566880039,
+ -5.0416453591327475,
+ -0.08384024903838053
+ ],
+ [
+ 8.50047405808511,
+ -0.3554294842220984,
+ 0.15942913832893682
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fuselage",
+ "name": "fuselage",
+ "private_attribute_tag_key": "groupName",
+ "private_attribute_sub_components": [
+ "body00001_face00005",
+ "body00001_face00006",
+ "body00001_face00007",
+ "body00001_face00008",
+ "body00001_face00009",
+ "body00001_face00010"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 0.0014996389999999999,
+ -0.45749012619146684,
+ -0.46072854876470765
+ ],
+ [
+ 10.0000001,
+ 0.4574901276161142,
+ 0.46072854876470765
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rightWing",
+ "name": "rightWing",
+ "private_attribute_tag_key": "groupName",
+ "private_attribute_sub_components": [
+ "body00001_face00011",
+ "body00001_face00012",
+ "body00001_face00013",
+ "body00001_face00014"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 2.9552725668800384,
+ 0.35542948383180295,
+ -0.08384024068111959
+ ],
+ [
+ 8.50047405808511,
+ 5.0416453591327475,
+ 0.15942913897469208
+ ]
+ ]
+ }
+ }
+ ]
+ },
+ "write_single_file": false,
+ "output_type": "SurfaceOutput"
+ },
+ {
+ "output_fields": {
+ "items": [
+ "Cp"
+ ]
+ },
+ "name": "Surface probe output",
+ "entities": {
+ "stored_entities": [
+ {
+ "private_attribute_registry_bucket_name": "PointEntityType",
+ "private_attribute_entity_type_name": "Point",
+ "private_attribute_id": "0978b673-79a7-4ad2-bc13-1ea47a6ab222",
+ "name": "1",
+ "location": {
+ "value": [
+ -1.0,
+ 0.0,
+ 0.0
+ ],
+ "units": "m"
+ }
+ }
+ ]
+ },
+ "target_surfaces": {
+ "stored_entities": [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "leftWing",
+ "name": "leftWing",
+ "private_attribute_tag_key": "groupName",
+ "private_attribute_sub_components": [
+ "body00001_face00001",
+ "body00001_face00002",
+ "body00001_face00003",
+ "body00001_face00004"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 2.955272566880039,
+ -5.0416453591327475,
+ -0.08384024903838053
+ ],
+ [
+ 8.50047405808511,
+ -0.3554294842220984,
+ 0.15942913832893682
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fuselage",
+ "name": "fuselage",
+ "private_attribute_tag_key": "groupName",
+ "private_attribute_sub_components": [
+ "body00001_face00005",
+ "body00001_face00006",
+ "body00001_face00007",
+ "body00001_face00008",
+ "body00001_face00009",
+ "body00001_face00010"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 0.0014996389999999999,
+ -0.45749012619146684,
+ -0.46072854876470765
+ ],
+ [
+ 10.0000001,
+ 0.4574901276161142,
+ 0.46072854876470765
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rightWing",
+ "name": "rightWing",
+ "private_attribute_tag_key": "groupName",
+ "private_attribute_sub_components": [
+ "body00001_face00011",
+ "body00001_face00012",
+ "body00001_face00013",
+ "body00001_face00014"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 2.9552725668800384,
+ 0.35542948383180295,
+ -0.08384024068111959
+ ],
+ [
+ 8.50047405808511,
+ 5.0416453591327475,
+ 0.15942913897469208
+ ]
+ ]
+ }
+ }
+ ]
+ },
+ "output_type": "SurfaceProbeOutput"
+ },
+ {
+ "output_fields": {
+ "items": [
+ "Cp"
+ ]
+ },
+ "frequency": -1,
+ "frequency_offset": 0,
+ "output_format": "paraview",
+ "name": "SurfaceSliceOutput",
+ "entities": {
+ "stored_entities": [
+ {
+ "private_attribute_registry_bucket_name": "SliceEntityType",
+ "private_attribute_entity_type_name": "Slice",
+ "private_attribute_id": "fcff645b-3591-4f96-a258-b1e3e87f5297",
+ "name": "slice",
+ "normal": [
+ 0.0,
+ 1.0,
+ 0.0
+ ],
+ "origin": {
+ "value": [
+ 0.0,
+ 0.0,
+ 0.0
+ ],
+ "units": "m"
+ }
+ }
+ ]
+ },
+ "target_surfaces": {
+ "stored_entities": [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "leftWing",
+ "name": "leftWing",
+ "private_attribute_tag_key": "groupName",
+ "private_attribute_sub_components": [
+ "body00001_face00001",
+ "body00001_face00002",
+ "body00001_face00003",
+ "body00001_face00004"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 2.955272566880039,
+ -5.0416453591327475,
+ -0.08384024903838053
+ ],
+ [
+ 8.50047405808511,
+ -0.3554294842220984,
+ 0.15942913832893682
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fuselage",
+ "name": "fuselage",
+ "private_attribute_tag_key": "groupName",
+ "private_attribute_sub_components": [
+ "body00001_face00005",
+ "body00001_face00006",
+ "body00001_face00007",
+ "body00001_face00008",
+ "body00001_face00009",
+ "body00001_face00010"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 0.0014996389999999999,
+ -0.45749012619146684,
+ -0.46072854876470765
+ ],
+ [
+ 10.0000001,
+ 0.4574901276161142,
+ 0.46072854876470765
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rightWing",
+ "name": "rightWing",
+ "private_attribute_tag_key": "groupName",
+ "private_attribute_sub_components": [
+ "body00001_face00011",
+ "body00001_face00012",
+ "body00001_face00013",
+ "body00001_face00014"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 2.9552725668800384,
+ 0.35542948383180295,
+ -0.08384024068111959
+ ],
+ [
+ 8.50047405808511,
+ 5.0416453591327475,
+ 0.15942913897469208
+ ]
+ ]
+ }
+ }
+ ]
+ },
+ "output_type": "SurfaceSliceOutput"
+ }
+ ],
+ "private_attribute_asset_cache": {
+ "project_length_unit": {
+ "value": 1.0,
+ "units": "m"
+ },
+ "project_entity_info": {
+ "draft_entities": [
+ {
+ "private_attribute_registry_bucket_name": "PointEntityType",
+ "private_attribute_entity_type_name": "Point",
+ "private_attribute_id": "0978b673-79a7-4ad2-bc13-1ea47a6ab222",
+ "name": "1",
+ "location": {
+ "value": [
+ -1.0,
+ 0.0,
+ 0.0
+ ],
+ "units": "m"
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SliceEntityType",
+ "private_attribute_entity_type_name": "Slice",
+ "private_attribute_id": "fcff645b-3591-4f96-a258-b1e3e87f5297",
+ "name": "slice",
+ "normal": [
+ 0.0,
+ 1.0,
+ 0.0
+ ],
+ "origin": {
+ "value": [
+ 0.0,
+ 0.0,
+ 0.0
+ ],
+ "units": "m"
+ }
+ }
+ ],
+ "ghost_entities": [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "GhostSphere",
+ "private_attribute_id": "farfield",
+ "name": "farfield",
+ "center": [
+ 0,
+ 0,
+ 0
+ ],
+ "max_radius": 504.16453591327473
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "GhostCircularPlane",
+ "private_attribute_id": "symmetric-1",
+ "name": "symmetric-1",
+ "center": [
+ 5.0007498695,
+ -5.0416453591327475,
+ 0.0
+ ],
+ "max_radius": 504.16453591327473,
+ "normal_axis": [
+ 0,
+ -1,
+ 0
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "GhostCircularPlane",
+ "private_attribute_id": "symmetric-2",
+ "name": "symmetric-2",
+ "center": [
+ 5.0007498695,
+ 5.0416453591327475,
+ 0.0
+ ],
+ "max_radius": 504.16453591327473,
+ "normal_axis": [
+ 0,
+ 1,
+ 0
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "GhostCircularPlane",
+ "private_attribute_id": "symmetric",
+ "name": "symmetric",
+ "center": [
+ 5.0007498695,
+ 0,
+ 0.0
+ ],
+ "max_radius": 504.16453591327473,
+ "normal_axis": [
+ 0,
+ 1,
+ 0
+ ]
+ }
+ ],
+ "type_name": "GeometryEntityInfo",
+ "body_ids": [
+ "body00001"
+ ],
+ "body_attribute_names": [
+ "bodyId",
+ "groupByFile"
+ ],
+ "grouped_bodies": [
+ [
+ {
+ "private_attribute_registry_bucket_name": "GeometryBodyGroupEntityType",
+ "private_attribute_entity_type_name": "GeometryBodyGroup",
+ "private_attribute_id": "body00001",
+ "name": "body00001",
+ "private_attribute_tag_key": "bodyId",
+ "private_attribute_sub_components": [
+ "body00001"
+ ],
+ "transformation": {
+ "type_name": "BodyGroupTransformation",
+ "origin": {
+ "value": [
+ 0.0,
+ 0.0,
+ 0.0
+ ],
+ "units": "m"
+ },
+ "axis_of_rotation": [
+ 1.0,
+ 0.0,
+ 0.0
+ ],
+ "angle_of_rotation": {
+ "value": 0.0,
+ "units": "degree"
+ },
+ "scale": [
+ 1.0,
+ 1.0,
+ 1.0
+ ],
+ "translation": {
+ "value": [
+ 0.0,
+ 0.0,
+ 0.0
+ ],
+ "units": "m"
+ }
+ },
+ "mesh_exterior": true
+ }
+ ],
+ [
+ {
+ "private_attribute_registry_bucket_name": "GeometryBodyGroupEntityType",
+ "private_attribute_entity_type_name": "GeometryBodyGroup",
+ "private_attribute_id": "geometry.csm",
+ "name": "geometry.csm",
+ "private_attribute_tag_key": "groupByFile",
+ "private_attribute_sub_components": [
+ "body00001"
+ ],
+ "transformation": {
+ "type_name": "BodyGroupTransformation",
+ "origin": {
+ "value": [
+ 0.0,
+ 0.0,
+ 0.0
+ ],
+ "units": "m"
+ },
+ "axis_of_rotation": [
+ 1.0,
+ 0.0,
+ 0.0
+ ],
+ "angle_of_rotation": {
+ "value": 0.0,
+ "units": "degree"
+ },
+ "scale": [
+ 1.0,
+ 1.0,
+ 1.0
+ ],
+ "translation": {
+ "value": [
+ 0.0,
+ 0.0,
+ 0.0
+ ],
+ "units": "m"
+ }
+ },
+ "mesh_exterior": true
+ }
+ ]
+ ],
+ "face_ids": [
+ "body00001_face00001",
+ "body00001_face00002",
+ "body00001_face00003",
+ "body00001_face00004",
+ "body00001_face00005",
+ "body00001_face00006",
+ "body00001_face00007",
+ "body00001_face00008",
+ "body00001_face00009",
+ "body00001_face00010",
+ "body00001_face00011",
+ "body00001_face00012",
+ "body00001_face00013",
+ "body00001_face00014"
+ ],
+ "face_attribute_names": [
+ "groupByBodyId",
+ "groupName",
+ "faceId"
+ ],
+ "grouped_faces": [
+ [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001",
+ "name": "body00001",
+ "private_attribute_tag_key": "groupByBodyId",
+ "private_attribute_sub_components": [
+ "body00001_face00001",
+ "body00001_face00002",
+ "body00001_face00003",
+ "body00001_face00004",
+ "body00001_face00005",
+ "body00001_face00006",
+ "body00001_face00007",
+ "body00001_face00008",
+ "body00001_face00009",
+ "body00001_face00010",
+ "body00001_face00011",
+ "body00001_face00012",
+ "body00001_face00013",
+ "body00001_face00014"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 0.0014996389999999999,
+ -5.0416453591327475,
+ -0.46072854876470765
+ ],
+ [
+ 10.0000001,
+ 5.0416453591327475,
+ 0.46072854876470765
+ ]
+ ]
+ }
+ }
+ ],
+ [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "leftWing",
+ "name": "leftWing",
+ "private_attribute_tag_key": "groupName",
+ "private_attribute_sub_components": [
+ "body00001_face00001",
+ "body00001_face00002",
+ "body00001_face00003",
+ "body00001_face00004"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 2.955272566880039,
+ -5.0416453591327475,
+ -0.08384024903838053
+ ],
+ [
+ 8.50047405808511,
+ -0.3554294842220984,
+ 0.15942913832893682
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "fuselage",
+ "name": "fuselage",
+ "private_attribute_tag_key": "groupName",
+ "private_attribute_sub_components": [
+ "body00001_face00005",
+ "body00001_face00006",
+ "body00001_face00007",
+ "body00001_face00008",
+ "body00001_face00009",
+ "body00001_face00010"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 0.0014996389999999999,
+ -0.45749012619146684,
+ -0.46072854876470765
+ ],
+ [
+ 10.0000001,
+ 0.4574901276161142,
+ 0.46072854876470765
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "rightWing",
+ "name": "rightWing",
+ "private_attribute_tag_key": "groupName",
+ "private_attribute_sub_components": [
+ "body00001_face00011",
+ "body00001_face00012",
+ "body00001_face00013",
+ "body00001_face00014"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 2.9552725668800384,
+ 0.35542948383180295,
+ -0.08384024068111959
+ ],
+ [
+ 8.50047405808511,
+ 5.0416453591327475,
+ 0.15942913897469208
+ ]
+ ]
+ }
+ }
+ ],
+ [
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00001",
+ "name": "body00001_face00001",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00001"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 6.649638643095831,
+ -5.001184995212779,
+ -0.0030114986389466842
+ ],
+ [
+ 8.50047405808511,
+ -0.3740967577395779,
+ 0.003011498638946684
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00002",
+ "name": "body00001_face00002",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00002"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 2.9552725668800393,
+ -5.000000100000003,
+ -0.08384024903838053
+ ],
+ [
+ 8.5000001,
+ -0.3699417805338956,
+ 7.341164861383231e-6
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00003",
+ "name": "body00001_face00003",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00003"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 7.499999899999163,
+ -5.0416453591327475,
+ -0.02231447247695361
+ ],
+ [
+ 8.50047405808511,
+ -4.999999899999996,
+ 0.042244450321219894
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00004",
+ "name": "body00001_face00004",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00004"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 2.955272566880039,
+ -5.000000100000003,
+ 1.8429789993335892e-6
+ ],
+ [
+ 8.5000001,
+ -0.3554294842220984,
+ 0.15942913832893682
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00005",
+ "name": "body00001_face00005",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00005"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 0.0014996389999999999,
+ -0.45749012619146684,
+ -0.46072854876470765
+ ],
+ [
+ 10.0000001,
+ 1e-7,
+ 0.46072854876470765
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00006",
+ "name": "body00001_face00006",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00006"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 0.001499739,
+ -0.01042075,
+ -0.01042075
+ ],
+ [
+ 0.001499739,
+ 0.0,
+ 0.01042075
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00007",
+ "name": "body00001_face00007",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00007"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 0.0014996389999999999,
+ -1.000000000564228e-7,
+ -0.46072854876470765
+ ],
+ [
+ 10.0000001,
+ 0.4574901276161142,
+ 0.46072854876470765
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00008",
+ "name": "body00001_face00008",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00008"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 10.0,
+ -0.03600338,
+ -0.03600338
+ ],
+ [
+ 10.0,
+ 0.0,
+ 0.03600338
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00009",
+ "name": "body00001_face00009",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00009"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 0.001499739,
+ -1.276173813221478e-18,
+ -0.01042075
+ ],
+ [
+ 0.001499739,
+ 0.01042075,
+ 0.01042075
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00010",
+ "name": "body00001_face00010",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00010"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 10.0,
+ -4.409142407548583e-18,
+ -0.03600338
+ ],
+ [
+ 10.0,
+ 0.03600338,
+ 0.03600338
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00011",
+ "name": "body00001_face00011",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00011"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 6.649638643095831,
+ 0.3740967577395779,
+ -0.0030114986389466842
+ ],
+ [
+ 8.50047405808511,
+ 5.001184995212779,
+ 0.003011498638946684
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00012",
+ "name": "body00001_face00012",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00012"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 2.9552725668800384,
+ 0.35542948383180295,
+ 1.8429789993335892e-6
+ ],
+ [
+ 8.5000001,
+ 5.000000100000003,
+ 0.15942913897469208
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00013",
+ "name": "body00001_face00013",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00013"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 2.9552725668800393,
+ 0.36994177538392403,
+ -0.08384024068111959
+ ],
+ [
+ 8.5000001,
+ 5.000000100000003,
+ 7.341164861407356e-6
+ ]
+ ]
+ }
+ },
+ {
+ "private_attribute_registry_bucket_name": "SurfaceEntityType",
+ "private_attribute_entity_type_name": "Surface",
+ "private_attribute_id": "body00001_face00014",
+ "name": "body00001_face00014",
+ "private_attribute_tag_key": "faceId",
+ "private_attribute_sub_components": [
+ "body00001_face00014"
+ ],
+ "private_attributes": {
+ "type_name": "SurfacePrivateAttributes",
+ "bounding_box": [
+ [
+ 7.499999899999163,
+ 4.999999899999996,
+ -0.02231447247695361
+ ],
+ [
+ 8.50047405808511,
+ 5.0416453591327475,
+ 0.042244450321219894
+ ]
+ ]
+ }
+ }
+ ]
+ ],
+ "edge_ids": [
+ "body00001_edge00001",
+ "body00001_edge00002",
+ "body00001_edge00004",
+ "body00001_edge00005",
+ "body00001_edge00006",
+ "body00001_edge00007",
+ "body00001_edge00008",
+ "body00001_edge00009",
+ "body00001_edge00010",
+ "body00001_edge00012",
+ "body00001_edge00013",
+ "body00001_edge00014",
+ "body00001_edge00015",
+ "body00001_edge00016",
+ "body00001_edge00017",
+ "body00001_edge00018",
+ "body00001_edge00019",
+ "body00001_edge00020",
+ "body00001_edge00021",
+ "body00001_edge00022",
+ "body00001_edge00023",
+ "body00001_edge00024",
+ "body00001_edge00025",
+ "body00001_edge00026",
+ "body00001_edge00027",
+ "body00001_edge00029",
+ "body00001_edge00030",
+ "body00001_edge00031",
+ "body00001_edge00032",
+ "body00001_edge00033"
+ ],
+ "edge_attribute_names": [
+ "edgeName",
+ "edgeId"
+ ],
+ "grouped_edges": [
+ [
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "trailingEdge",
+ "name": "trailingEdge",
+ "private_attribute_tag_key": "edgeName",
+ "private_attribute_sub_components": [
+ "body00001_edge00001",
+ "body00001_edge00005",
+ "body00001_edge00026",
+ "body00001_edge00030"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "leadingEdge",
+ "name": "leadingEdge",
+ "private_attribute_tag_key": "edgeName",
+ "private_attribute_sub_components": [
+ "body00001_edge00007",
+ "body00001_edge00032"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00002",
+ "name": "body00001_edge00002",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00002"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00004",
+ "name": "body00001_edge00004",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00004"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00006",
+ "name": "body00001_edge00006",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00006"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00008",
+ "name": "body00001_edge00008",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00008"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00009",
+ "name": "body00001_edge00009",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00009"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00010",
+ "name": "body00001_edge00010",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00010"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00012",
+ "name": "body00001_edge00012",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00012"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00013",
+ "name": "body00001_edge00013",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00013"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00014",
+ "name": "body00001_edge00014",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00014"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00015",
+ "name": "body00001_edge00015",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00015"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00016",
+ "name": "body00001_edge00016",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00016"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00017",
+ "name": "body00001_edge00017",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00017"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00018",
+ "name": "body00001_edge00018",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00018"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00019",
+ "name": "body00001_edge00019",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00019"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00020",
+ "name": "body00001_edge00020",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00020"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00021",
+ "name": "body00001_edge00021",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00021"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00022",
+ "name": "body00001_edge00022",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00022"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00023",
+ "name": "body00001_edge00023",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00023"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00024",
+ "name": "body00001_edge00024",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00024"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00025",
+ "name": "body00001_edge00025",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00025"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00027",
+ "name": "body00001_edge00027",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00027"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00029",
+ "name": "body00001_edge00029",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00029"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00031",
+ "name": "body00001_edge00031",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00031"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00033",
+ "name": "body00001_edge00033",
+ "private_attribute_tag_key": "__standalone__",
+ "private_attribute_sub_components": [
+ "body00001_edge00033"
+ ]
+ }
+ ],
+ [
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00001",
+ "name": "body00001_edge00001",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00001"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00002",
+ "name": "body00001_edge00002",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00002"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00004",
+ "name": "body00001_edge00004",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00004"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00005",
+ "name": "body00001_edge00005",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00005"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00006",
+ "name": "body00001_edge00006",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00006"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00007",
+ "name": "body00001_edge00007",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00007"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00008",
+ "name": "body00001_edge00008",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00008"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00009",
+ "name": "body00001_edge00009",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00009"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00010",
+ "name": "body00001_edge00010",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00010"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00012",
+ "name": "body00001_edge00012",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00012"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00013",
+ "name": "body00001_edge00013",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00013"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00014",
+ "name": "body00001_edge00014",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00014"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00015",
+ "name": "body00001_edge00015",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00015"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00016",
+ "name": "body00001_edge00016",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00016"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00017",
+ "name": "body00001_edge00017",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00017"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00018",
+ "name": "body00001_edge00018",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00018"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00019",
+ "name": "body00001_edge00019",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00019"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00020",
+ "name": "body00001_edge00020",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00020"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00021",
+ "name": "body00001_edge00021",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00021"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00022",
+ "name": "body00001_edge00022",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00022"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00023",
+ "name": "body00001_edge00023",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00023"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00024",
+ "name": "body00001_edge00024",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00024"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00025",
+ "name": "body00001_edge00025",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00025"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00026",
+ "name": "body00001_edge00026",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00026"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00027",
+ "name": "body00001_edge00027",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00027"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00029",
+ "name": "body00001_edge00029",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00029"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00030",
+ "name": "body00001_edge00030",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00030"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00031",
+ "name": "body00001_edge00031",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00031"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00032",
+ "name": "body00001_edge00032",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00032"
+ ]
+ },
+ {
+ "private_attribute_registry_bucket_name": "EdgeEntityType",
+ "private_attribute_entity_type_name": "Edge",
+ "private_attribute_id": "body00001_edge00033",
+ "name": "body00001_edge00033",
+ "private_attribute_tag_key": "edgeId",
+ "private_attribute_sub_components": [
+ "body00001_edge00033"
+ ]
+ }
+ ]
+ ],
+ "body_group_tag": "groupByFile",
+ "face_group_tag": "groupName",
+ "edge_group_tag": "edgeName",
+ "global_bounding_box": [
+ [
+ 0.0014996389999999999,
+ -5.0416453591327475,
+ -0.46072854876470765
+ ],
+ [
+ 10.0000001,
+ 5.0416453591327475,
+ 0.46072854876470765
+ ]
+ ]
+ },
+ "use_inhouse_mesher": false,
+ "use_geometry_AI": false
+ }
+}
\ No newline at end of file
diff --git a/tests/simulation/service/test_integration_metadata.py b/tests/simulation/service/test_integration_metadata.py
index 3b714cba8..00c5ac027 100644
--- a/tests/simulation/service/test_integration_metadata.py
+++ b/tests/simulation/service/test_integration_metadata.py
@@ -66,6 +66,36 @@ def get_volume_mesh_metadata():
}
+@pytest.fixture()
+def get_snappy_like_volume_mesh_metadata():
+ """A realistic volume mesh metadata from snappy surface mesh w. multizone."""
+ return {
+ "zones": {
+ "fluid": {
+ "boundaryNames": [
+ "fluid/box::ground",
+ "fluid/box::walls",
+ "fluid/tower::tunnel",
+ "fluid/tower::walls",
+ ],
+ "donorInterfaceNames": ["radiator/rad::int-inlet", "radiator/rad::int-outlet"],
+ "donorZoneNames": ["radiator", "radiator"],
+ "receiverInterfaceNames": ["fluid/rad::int-inlet", "fluid/rad::int-outlet"],
+ },
+ "radiator": {
+ "boundaryNames": [
+ "radiator/rad::int-inlet",
+ "radiator/rad::int-outlet",
+ "radiator/tower::tunnel",
+ ],
+ "donorInterfaceNames": ["fluid/rad::int-inlet", "fluid/rad::int-outlet"],
+ "donorZoneNames": ["fluid", "fluid"],
+ "receiverInterfaceNames": ["radiator/rad::int-inlet", "radiator/rad::int-outlet"],
+ },
+ }
+ }
+
+
def test_update_zone_info_from_volume_mesh(get_volume_mesh_metadata):
# Param is generated before the volume mesh metadata is available AKA the param generated the volume mesh.
# (Though the volume meshing params are skipped here)
diff --git a/tests/simulation/translator/ref/Flow360_boundaries.json b/tests/simulation/translator/ref/Flow360_boundaries.json
index c927780a4..6cef92210 100644
--- a/tests/simulation/translator/ref/Flow360_boundaries.json
+++ b/tests/simulation/translator/ref/Flow360_boundaries.json
@@ -211,4 +211,4 @@
"shouldCheckStopCriterion": false,
"externalProcessMonitorOutput": false
}
-}
+}
\ No newline at end of file
diff --git a/tests/simulation/translator/ref/Flow360_liquid.json b/tests/simulation/translator/ref/Flow360_liquid.json
index 64f364fc9..2922f6a19 100644
--- a/tests/simulation/translator/ref/Flow360_liquid.json
+++ b/tests/simulation/translator/ref/Flow360_liquid.json
@@ -106,4 +106,4 @@
"shouldCheckStopCriterion": false,
"externalProcessMonitorOutput": false
}
-}
\ No newline at end of file
+}
diff --git a/tests/simulation/translator/ref/Flow360_liquid_rotation_dd.json b/tests/simulation/translator/ref/Flow360_liquid_rotation_dd.json
index 5c1026a2e..919be4b0e 100644
--- a/tests/simulation/translator/ref/Flow360_liquid_rotation_dd.json
+++ b/tests/simulation/translator/ref/Flow360_liquid_rotation_dd.json
@@ -140,4 +140,4 @@
"shouldCheckStopCriterion": false,
"externalProcessMonitorOutput": false
}
-}
\ No newline at end of file
+}
diff --git a/tests/simulation/translator/ref/Flow360_liquid_rotation_dd_with_ref_vel.json b/tests/simulation/translator/ref/Flow360_liquid_rotation_dd_with_ref_vel.json
index 27f7752e4..17c4a53e8 100644
--- a/tests/simulation/translator/ref/Flow360_liquid_rotation_dd_with_ref_vel.json
+++ b/tests/simulation/translator/ref/Flow360_liquid_rotation_dd_with_ref_vel.json
@@ -141,4 +141,4 @@
"shouldCheckStopCriterion": false,
"externalProcessMonitorOutput": false
}
-}
\ No newline at end of file
+}
diff --git a/tests/simulation/translator/ref/Flow360_user_variable.json b/tests/simulation/translator/ref/Flow360_user_variable.json
index 430111a47..629d24bb4 100644
--- a/tests/simulation/translator/ref/Flow360_user_variable.json
+++ b/tests/simulation/translator/ref/Flow360_user_variable.json
@@ -342,4 +342,4 @@
"shouldCheckStopCriterion": false,
"externalProcessMonitorOutput": false
}
-}
\ No newline at end of file
+}
diff --git a/tests/simulation/translator/ref/surface_meshing/default_snappy.json b/tests/simulation/translator/ref/surface_meshing/default_snappy.json
new file mode 100644
index 000000000..330126366
--- /dev/null
+++ b/tests/simulation/translator/ref/surface_meshing/default_snappy.json
@@ -0,0 +1,104 @@
+{
+ "geometry": {
+ "bodies": [
+ {
+ "bodyName": "body0",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0"
+ },
+ {
+ "patchName": "patch1"
+ }
+ ]
+ },
+ {
+ "bodyName": "body1",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0"
+ },
+ {
+ "patchName": "patch1"
+ },
+ {
+ "patchName": "patch2"
+ }
+ ]
+ },
+ {
+ "bodyName": "body2",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0"
+ }
+ ]
+ },
+ {
+ "bodyName": "body3",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0"
+ }
+ ]
+ }
+ ]
+ },
+ "mesherSettings": {
+ "snappyHexMesh": {
+ "castellatedMeshControls": {
+ "resolveFeatureAngle": 25,
+ "nCellsBetweenLevels": 1,
+ "minRefinementCells": 10
+ },
+ "snapControls": {
+ "nSmoothPatch": 3,
+ "tolerance": 2,
+ "nSolveIter": 30,
+ "nRelaxIter": 5,
+ "nFeatureSnapIter": 15,
+ "multiRegionFeatureSnap": true,
+ "strictRegionSnap": false
+ }
+ },
+ "meshQuality": {
+ "maxNonOrtho": 85,
+ "maxBoundarySkewness": 20,
+ "maxInternalSkewness": 50,
+ "maxConcave": 50,
+ "minVol": -1e+30,
+ "minTetQuality": -1e+30,
+ "minArea": -1,
+ "minTwist": -2,
+ "minDeterminant": -1e+30,
+ "minVolRatio": 0,
+ "minFaceWeight": 0,
+ "minTriangleTwist": -1,
+ "nSmoothScale": 4,
+ "errorReduction": 0.75,
+ "minVolCollapseRatio": 0
+ }
+ },
+ "cadIsFluid": false,
+ "enforcedSpacing": 1
+}
\ No newline at end of file
diff --git a/tests/simulation/translator/ref/surface_meshing/snappy_basic_refinements.json b/tests/simulation/translator/ref/surface_meshing/snappy_basic_refinements.json
new file mode 100644
index 000000000..1eb9dded2
--- /dev/null
+++ b/tests/simulation/translator/ref/surface_meshing/snappy_basic_refinements.json
@@ -0,0 +1,202 @@
+{
+ "geometry": {
+ "bodies": [
+ {
+ "bodyName": "body0",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0",
+ "spacing": {
+ "min": 20,
+ "max": 40
+ },
+ "gapSpacingReduction": 3,
+ "edges":{
+ "edgeSpacing": [[5, 4]],
+ "minElem": 3,
+ "includedAngle": 120,
+ "retainOnSmoothing": true
+ }
+ },
+ {
+ "patchName": "patch1",
+ "edges":{
+ "edgeSpacing": [
+ [
+ 1,
+ 3
+ ],
+ [
+ 3,
+ 5
+ ]
+ ],
+ "minLen": 6,
+ "includedAngle": 150,
+ "retainOnSmoothing": false
+ }
+ }
+ ]
+ },
+ {
+ "bodyName": "body1",
+ "gap": 2,
+ "spacing": {
+ "min": 5,
+ "max": 10
+ },
+ "edges":{
+ "edgeSpacing": 4,
+ "minElem": 3,
+ "includedAngle": 120,
+ "retainOnSmoothing": true
+ },
+ "regions": [
+ {
+ "patchName": "patch0"
+ },
+ {
+ "patchName": "patch1",
+ "spacing": {
+ "min": 20,
+ "max": 40
+ },
+ "gapSpacingReduction": 3,
+ "edges":{
+ "edgeSpacing": [
+ [
+ 1,
+ 3
+ ],
+ [
+ 3,
+ 5
+ ]
+ ],
+ "minLen": 6,
+ "includedAngle": 150,
+ "retainOnSmoothing": false
+ }
+ },
+ {
+ "patchName": "patch2"
+ }
+ ]
+ },
+ {
+ "bodyName": "body2",
+ "gap": 0.5,
+ "gapSpacingReduction": 0.2,
+ "spacing": {
+ "min": 1,
+ "max": 2
+ },
+ "regions": [
+ {
+ "patchName": "patch0"
+ }
+ ]
+ },
+ {
+ "bodyName": "body3",
+ "gap": 2,
+ "spacing": {
+ "min": 5,
+ "max": 10
+ },
+ "edges":{
+ "edgeSpacing": [
+ [
+ 1,
+ 3
+ ],
+ [
+ 3,
+ 5
+ ]
+ ],
+ "minLen": 6,
+ "includedAngle": 150,
+ "retainOnSmoothing": false
+ },
+ "regions": [
+ {
+ "patchName": "patch0"
+ }
+ ]
+ }
+ ],
+ "refinementVolumes": [
+ {
+ "type": "box",
+ "min": {"x": -10, "y": 15, "z": 40},
+ "max": {"x": 10, "y": 45, "z": 80},
+ "name": "box0",
+ "spacing": 2
+ },
+ {
+ "type": "cylinder",
+ "point1": {"x": 10, "y": 20, "z": 0},
+ "point2": {"x": 10, "y": 20, "z": 60},
+ "radius": 20,
+ "name": "cyl0",
+ "spacing": 2
+ },
+ {
+ "type": "cylinder",
+ "point1": {"x": 21.5634892, "y": -0.0137314, "z": 49.1242323},
+ "point2": {"x": -1.5634892, "y": 40.0137314, "z": 10.8757677},
+ "radius": 34,
+ "name": "cyl1",
+ "spacing": 8
+ }
+ ]
+ },
+ "mesherSettings": {
+ "snappyHexMesh": {
+ "castellatedMeshControls": {
+ "resolveFeatureAngle": 25,
+ "nCellsBetweenLevels": 1,
+ "minRefinementCells": 10
+ },
+ "snapControls": {
+ "nSmoothPatch": 3,
+ "tolerance": 2,
+ "nSolveIter": 30,
+ "nRelaxIter": 5,
+ "nFeatureSnapIter": 15,
+ "multiRegionFeatureSnap": true,
+ "strictRegionSnap": false
+ }
+ },
+ "meshQuality": {
+ "maxNonOrtho": 85,
+ "maxBoundarySkewness": 20,
+ "maxInternalSkewness": 50,
+ "maxConcave": 50,
+ "minVol": -1e+30,
+ "minTetQuality": -1e+30,
+ "minArea": -1,
+ "minTwist": -2,
+ "minDeterminant": -1e+30,
+ "minVolRatio": 0,
+ "minFaceWeight": 0,
+ "minTriangleTwist": -1,
+ "nSmoothScale": 4,
+ "errorReduction": 0.75,
+ "minVolCollapseRatio": 0
+ }
+ },
+ "smoothingControls": {
+ "lambda": 0.7,
+ "mu": 0.71,
+ "iter": 5
+ },
+ "cadIsFluid": false,
+ "enforcedSpacing": 3.5
+}
\ No newline at end of file
diff --git a/tests/simulation/translator/ref/surface_meshing/snappy_coupled_refinements.json b/tests/simulation/translator/ref/surface_meshing/snappy_coupled_refinements.json
new file mode 100644
index 000000000..f49e626d8
--- /dev/null
+++ b/tests/simulation/translator/ref/surface_meshing/snappy_coupled_refinements.json
@@ -0,0 +1,129 @@
+{
+ "geometry": {
+ "bodies": [
+ {
+ "bodyName": "body0",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0"
+ },
+ {
+ "patchName": "patch1"
+ }
+ ]
+ },
+ {
+ "bodyName": "body1",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0"
+ },
+ {
+ "patchName": "patch1"
+ },
+ {
+ "patchName": "patch2"
+ }
+ ]
+ },
+ {
+ "bodyName": "body2",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0"
+ }
+ ]
+ },
+ {
+ "bodyName": "body3",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0"
+ }
+ ]
+ }
+ ],
+ "refinementVolumes": [
+ {
+ "type": "box",
+ "min": {"x": -10, "y": 15, "z": 40},
+ "max": {"x": 10, "y": 45, "z": 80},
+ "name": "box0",
+ "spacing": 2
+ },
+ {
+ "type": "cylinder",
+ "point1": {"x": 10, "y": 20, "z": 0},
+ "point2": {"x": 10, "y": 20, "z": 60},
+ "radius": 20,
+ "name": "cyl0",
+ "spacing": 2
+ }
+ ]
+ },
+ "mesherSettings": {
+ "snappyHexMesh": {
+ "castellatedMeshControls": {
+ "resolveFeatureAngle": 25,
+ "nCellsBetweenLevels": 1,
+ "minRefinementCells": 10
+ },
+ "snapControls": {
+ "nSmoothPatch": 3,
+ "tolerance": 2,
+ "nSolveIter": 30,
+ "nRelaxIter": 5,
+ "nFeatureSnapIter": 15,
+ "multiRegionFeatureSnap": true,
+ "strictRegionSnap": false
+ }
+ },
+ "meshQuality": {
+ "maxNonOrtho": 85,
+ "maxBoundarySkewness": 20,
+ "maxInternalSkewness": 50,
+ "maxConcave": 50,
+ "minVol": -1e+30,
+ "minTetQuality": -1e+30,
+ "minArea": -1,
+ "minTwist": -2,
+ "minDeterminant": -1e+30,
+ "minVolRatio": 0,
+ "minFaceWeight": 0,
+ "minTriangleTwist": -1,
+ "nSmoothScale": 4,
+ "errorReduction": 0.75,
+ "minVolCollapseRatio": 0
+ }
+ },
+ "smoothingControls": {
+ "lambda": 0.7,
+ "mu": 0.71,
+ "iter": 5
+ },
+ "locationInMesh": {
+ "farfield": [0, 0, 0]
+ },
+ "cadIsFluid": true,
+ "enforcedSpacing": 5
+}
\ No newline at end of file
diff --git a/tests/simulation/translator/ref/surface_meshing/snappy_no_regions.json b/tests/simulation/translator/ref/surface_meshing/snappy_no_regions.json
new file mode 100644
index 000000000..585a77d31
--- /dev/null
+++ b/tests/simulation/translator/ref/surface_meshing/snappy_no_regions.json
@@ -0,0 +1,85 @@
+{
+ "geometry": {
+ "bodies": [
+ {
+ "bodyName": "body01_face001",
+ "gap": 2,
+ "spacing": {
+ "min": 5,
+ "max": 10
+ },
+ "regions": []
+ },
+ {
+ "bodyName": "body01_face002",
+ "gap": 0.5,
+ "gapSpacingReduction": 0.2,
+ "spacing": {
+ "min": 1,
+ "max": 2
+ },
+ "regions": []
+ },
+ {
+ "bodyName": "body01_face003",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "edges":{
+ "edgeSpacing": 4,
+ "minElem": 3,
+ "includedAngle": 120,
+ "retainOnSmoothing": true
+ },
+ "regions": []
+ }
+ ]
+ },
+ "mesherSettings": {
+ "snappyHexMesh": {
+ "castellatedMeshControls": {
+ "resolveFeatureAngle": 25,
+ "nCellsBetweenLevels": 1,
+ "minRefinementCells": 10
+ },
+ "snapControls": {
+ "nSmoothPatch": 3,
+ "tolerance": 2,
+ "nSolveIter": 30,
+ "nRelaxIter": 5,
+ "nFeatureSnapIter": 15,
+ "multiRegionFeatureSnap": true,
+ "strictRegionSnap": false
+ }
+ },
+ "meshQuality": {
+ "maxNonOrtho": 85,
+ "maxBoundarySkewness": 20,
+ "maxInternalSkewness": 50,
+ "maxConcave": 50,
+ "minVol": -1e+30,
+ "minTetQuality": -1e+30,
+ "minArea": -1,
+ "minTwist": -2,
+ "minDeterminant": -1e+30,
+ "minVolRatio": 0,
+ "minFaceWeight": 0,
+ "minTriangleTwist": -1,
+ "nSmoothScale": 4,
+ "errorReduction": 0.75,
+ "minVolCollapseRatio": 0
+ }
+ },
+ "smoothingControls": {
+ "lambda": 0.7,
+ "mu": 0.71,
+ "iter": 5
+ },
+ "locationInMesh": {
+ "fluid": [0, 0, 0]
+ },
+ "cadIsFluid": true,
+ "enforcedSpacing": 1
+}
\ No newline at end of file
diff --git a/tests/simulation/translator/ref/surface_meshing/snappy_refinements_multiple_regions.json b/tests/simulation/translator/ref/surface_meshing/snappy_refinements_multiple_regions.json
new file mode 100644
index 000000000..84638bd6d
--- /dev/null
+++ b/tests/simulation/translator/ref/surface_meshing/snappy_refinements_multiple_regions.json
@@ -0,0 +1,152 @@
+{
+ "geometry": {
+ "bodies": [
+ {
+ "bodyName": "body0",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0",
+ "spacing": {
+ "min": 10,
+ "max": 40
+ },
+ "edges":{
+ "edgeSpacing": 4,
+ "minElem": 3,
+ "includedAngle": 120,
+ "retainOnSmoothing": false
+ }
+ },
+ {
+ "patchName": "patch1",
+ "spacing": {
+ "min": 10,
+ "max": 40
+ },
+ "edges":{
+ "edgeSpacing": 4,
+ "minElem": 3,
+ "includedAngle": 120,
+ "retainOnSmoothing": false
+ }
+ }
+ ]
+ },
+ {
+ "bodyName": "body1",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0",
+ "gapSpacingReduction": 3,
+ "spacing": {
+ "min": 20,
+ "max": 40
+ }
+ },
+ {
+ "patchName": "patch1",
+ "gapSpacingReduction": 3,
+ "spacing": {
+ "min": 20,
+ "max": 40
+ }
+ },
+ {
+ "patchName": "patch2",
+ "gapSpacingReduction": 3,
+ "spacing": {
+ "min": 20,
+ "max": 40
+ }
+ }
+ ]
+ },
+ {
+ "bodyName": "body2",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0",
+ "spacing": {
+ "min": 5,
+ "max": 40
+ }
+ }
+ ]
+ },
+ {
+ "bodyName": "body3",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0",
+ "spacing": {
+ "min": 5,
+ "max": 40
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "mesherSettings": {
+ "snappyHexMesh": {
+ "castellatedMeshControls": {
+ "resolveFeatureAngle": 25,
+ "nCellsBetweenLevels": 1,
+ "minRefinementCells": 10
+ },
+ "snapControls": {
+ "nSmoothPatch": 3,
+ "tolerance": 2,
+ "nSolveIter": 30,
+ "nRelaxIter": 5,
+ "nFeatureSnapIter": 15,
+ "multiRegionFeatureSnap": true,
+ "strictRegionSnap": false
+ }
+ },
+ "meshQuality": {
+ "maxNonOrtho": 85,
+ "maxBoundarySkewness": 20,
+ "maxInternalSkewness": 50,
+ "maxConcave": 50,
+ "minVol": -1e+30,
+ "minTetQuality": -1e+30,
+ "minArea": -1,
+ "minTwist": -2,
+ "minDeterminant": -1e+30,
+ "minVolRatio": 0,
+ "minFaceWeight": 0,
+ "minTriangleTwist": -1,
+ "nSmoothScale": 4,
+ "errorReduction": 0.75,
+ "minVolCollapseRatio": 0
+ }
+ },
+ "smoothingControls": {
+ "lambda": 0.7,
+ "mu": 0.71,
+ "iter": 5
+ },
+ "cadIsFluid": false,
+ "enforcedSpacing": 3
+}
\ No newline at end of file
diff --git a/tests/simulation/translator/ref/surface_meshing/snappy_settings.json b/tests/simulation/translator/ref/surface_meshing/snappy_settings.json
new file mode 100644
index 000000000..b75b1fe21
--- /dev/null
+++ b/tests/simulation/translator/ref/surface_meshing/snappy_settings.json
@@ -0,0 +1,113 @@
+{
+ "geometry": {
+ "bodies": [
+ {
+ "bodyName": "body0",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0"
+ },
+ {
+ "patchName": "patch1"
+ }
+ ]
+ },
+ {
+ "bodyName": "body1",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0"
+ },
+ {
+ "patchName": "patch1"
+ },
+ {
+ "patchName": "patch2"
+ }
+ ]
+ },
+ {
+ "bodyName": "body2",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0"
+ }
+ ]
+ },
+ {
+ "bodyName": "body3",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0"
+ }
+ ]
+ }
+ ]
+ },
+ "mesherSettings": {
+ "snappyHexMesh": {
+ "castellatedMeshControls": {
+ "resolveFeatureAngle": 10,
+ "nCellsBetweenLevels": 3,
+ "minRefinementCells": 50
+ },
+ "snapControls": {
+ "nSmoothPatch": 5,
+ "tolerance": 4,
+ "nSolveIter": 20,
+ "nRelaxIter": 2,
+ "nFeatureSnapIter": 10,
+ "multiRegionFeatureSnap": false,
+ "strictRegionSnap": true
+ }
+ },
+ "meshQuality": {
+ "maxNonOrtho": 55,
+ "maxBoundarySkewness": 30,
+ "maxInternalSkewness": 70,
+ "maxConcave": 20,
+ "minVol": 1e-2,
+ "minTetQuality": 0.15,
+ "minArea": 2,
+ "minTwist": 0.3,
+ "minDeterminant": 0.5,
+ "minVolRatio": 0.1,
+ "minFaceWeight": 0.3,
+ "minTriangleTwist": 0.1,
+ "nSmoothScale": 6,
+ "errorReduction": 0.4,
+ "minVolCollapseRatio": 0.5
+ }
+ },
+ "smoothingControls": {
+ "lambda": 0.3,
+ "mu": 0.31,
+ "iter": 5
+ },
+ "locationInMesh": {
+ "fluid": [0, 0, 0],
+ "solid": [1, 2, 3]
+ },
+ "cadIsFluid": true,
+ "enforcedSpacing": 1
+}
\ No newline at end of file
diff --git a/tests/simulation/translator/ref/surface_meshing/snappy_settings_off_pos.json b/tests/simulation/translator/ref/surface_meshing/snappy_settings_off_pos.json
new file mode 100644
index 000000000..c1cf8960e
--- /dev/null
+++ b/tests/simulation/translator/ref/surface_meshing/snappy_settings_off_pos.json
@@ -0,0 +1,113 @@
+{
+ "geometry": {
+ "bodies": [
+ {
+ "bodyName": "body0",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0"
+ },
+ {
+ "patchName": "patch1"
+ }
+ ]
+ },
+ {
+ "bodyName": "body1",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0"
+ },
+ {
+ "patchName": "patch1"
+ },
+ {
+ "patchName": "patch2"
+ }
+ ]
+ },
+ {
+ "bodyName": "body2",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0"
+ }
+ ]
+ },
+ {
+ "bodyName": "body3",
+ "gap": 1,
+ "spacing": {
+ "min": 3,
+ "max": 4
+ },
+ "regions": [
+ {
+ "patchName": "patch0"
+ }
+ ]
+ }
+ ]
+ },
+ "mesherSettings": {
+ "snappyHexMesh": {
+ "castellatedMeshControls": {
+ "resolveFeatureAngle": 10,
+ "nCellsBetweenLevels": 3,
+ "minRefinementCells": 50
+ },
+ "snapControls": {
+ "nSmoothPatch": 5,
+ "tolerance": 4,
+ "nSolveIter": 20,
+ "nRelaxIter": 2,
+ "nFeatureSnapIter": 10,
+ "multiRegionFeatureSnap": false,
+ "strictRegionSnap": true
+ }
+ },
+ "meshQuality": {
+ "maxNonOrtho": 180,
+ "maxBoundarySkewness": -1,
+ "maxInternalSkewness": -1,
+ "maxConcave": 180,
+ "minVol": -1e30,
+ "minTetQuality": -1e30,
+ "minArea": -1,
+ "minTwist": -2,
+ "minDeterminant": -1e+30,
+ "minVolRatio": 0,
+ "minFaceWeight": 0,
+ "minTriangleTwist": -1,
+ "nSmoothScale": 0,
+ "errorReduction": 0,
+ "minVolCollapseRatio": 0
+ }
+ },
+ "smoothingControls": {
+ "lambda": 0.7,
+ "mu": 0.71,
+ "iter": 0
+ },
+ "locationInMesh": {
+ "fluid": [0, 0, 0],
+ "solid": [1, 2, 3]
+ },
+ "cadIsFluid": true,
+ "enforcedSpacing": 1
+}
\ No newline at end of file
diff --git a/tests/simulation/translator/test_output_translation.py b/tests/simulation/translator/test_output_translation.py
index bb5e288b9..c8fd3f13a 100644
--- a/tests/simulation/translator/test_output_translation.py
+++ b/tests/simulation/translator/test_output_translation.py
@@ -1019,7 +1019,6 @@ def test_probe_output(
translated = {"boundaries": {}}
translated = translate_output(param, translated)
-
assert compare_values(probe_output_config[1], translated["monitorOutput"])
##:: monitorOutput with line probes
diff --git a/tests/simulation/translator/test_solver_translator.py b/tests/simulation/translator/test_solver_translator.py
index c4a69f5bb..8d054b368 100644
--- a/tests/simulation/translator/test_solver_translator.py
+++ b/tests/simulation/translator/test_solver_translator.py
@@ -8,10 +8,8 @@
import flow360.component.simulation.units as u
from flow360.component.simulation.entity_info import SurfaceMeshEntityInfo
from flow360.component.simulation.framework.param_utils import AssetCache
-from flow360.component.simulation.meshing_param.params import (
- MeshingDefaults,
- MeshingParams,
-)
+from flow360.component.simulation.meshing_param.meshing_specs import MeshingDefaults
+from flow360.component.simulation.meshing_param.params import MeshingParams
from flow360.component.simulation.meshing_param.volume_params import UserDefinedFarfield
from flow360.component.simulation.models.material import Water, aluminum
from flow360.component.simulation.models.solver_numerics import (
@@ -1329,7 +1327,6 @@ def test_custom_volume_translation():
),
volume_zones=[
CustomVolume(name="zone1", boundaries=[Surface(name="face1")]),
- UserDefinedFarfield(),
zone_2,
],
),
diff --git a/tests/simulation/translator/test_surface_meshing_translator.py b/tests/simulation/translator/test_surface_meshing_translator.py
index fc478387f..55d6e8231 100644
--- a/tests/simulation/translator/test_surface_meshing_translator.py
+++ b/tests/simulation/translator/test_surface_meshing_translator.py
@@ -5,6 +5,7 @@
import flow360.component.simulation.units as u
from flow360.component.geometry import Geometry, GeometryMeta
+from flow360.component.project_utils import validate_params_with_context
from flow360.component.resource_base import local_metadata_builder
from flow360.component.simulation.entity_info import GeometryEntityInfo
from flow360.component.simulation.entity_operation import Transformation
@@ -21,15 +22,41 @@
GeometryRefinement,
SurfaceRefinement,
)
+from flow360.component.simulation.meshing_param.meshing_specs import (
+ BetaVolumeMeshingDefaults,
+ SnappyCastellatedMeshControls,
+ SnappyQualityMetrics,
+ SnappySmoothControls,
+ SnappySnapControls,
+ SnappySurfaceMeshingDefaults,
+)
from flow360.component.simulation.meshing_param.params import (
+ BetaVolumeMeshingParams,
MeshingDefaults,
MeshingParams,
+ ModularMeshingWorkflow,
+ SnappySurfaceMeshingParams,
+)
+from flow360.component.simulation.meshing_param.surface_mesh_refinements import (
+ SnappyBodyRefinement,
+ SnappyRegionRefinement,
+ SnappySurfaceEdgeRefinement,
+)
+from flow360.component.simulation.meshing_param.volume_params import (
+ AutomatedFarfield,
+ UniformRefinement,
)
-from flow360.component.simulation.meshing_param.volume_params import AutomatedFarfield
from flow360.component.simulation.operating_condition.operating_condition import (
AerospaceCondition,
)
-from flow360.component.simulation.primitives import Edge, Surface
+from flow360.component.simulation.primitives import (
+ Box,
+ Cylinder,
+ Edge,
+ SeedpointZone,
+ SnappyBody,
+ Surface,
+)
from flow360.component.simulation.simulation_params import SimulationParams
from flow360.component.simulation.translator.surface_meshing_translator import (
get_surface_meshing_json,
@@ -94,6 +121,28 @@ def _get_meta_data(self):
},
"mesh_unit": {"units": "inch", "value": 1.0},
}
+ elif self.fname == "tester.stl":
+ return {
+ "surfaces": {
+ "body0::patch0": {},
+ "body0::patch1": {},
+ "body1::patch0": {},
+ "body1::patch1": {},
+ "body1::patch2": {},
+ "body2::patch0": {},
+ "body3::patch0": {},
+ },
+ "mesh_unit": {"units": "mm", "value": 1.0},
+ }
+ elif self.fname == "tester_no_naming.stl":
+ return {
+ "surfaces": {
+ "body01_face001": {},
+ "body01_face002": {},
+ "body01_face003": {},
+ },
+ "mesh_unit": {"units": "mm", "value": 1.0},
+ }
else:
raise ValueError("Invalid file name")
@@ -194,28 +243,107 @@ def _get_entity_info(self):
],
)
r
+ elif self.fname == "tester.stl":
+ return GeometryEntityInfo(
+ face_ids=[
+ "body0::patch0",
+ "body0::patch1",
+ "body1::patch0",
+ "body1::patch1",
+ "body1::patch2",
+ "body2::patch0",
+ "body3::patch0",
+ ],
+ edge_ids=[],
+ face_attribute_names=["faceId"],
+ face_group_tag="dummy",
+ grouped_faces=[
+ [
+ Surface(
+ name="body0::patch0",
+ private_attribute_sub_components=["body0::patch0"],
+ ),
+ Surface(
+ name="body0::patch1",
+ private_attribute_sub_components=["body0::patch1"],
+ ),
+ Surface(
+ name="body1::patch0",
+ private_attribute_sub_components=["body1::patch0"],
+ ),
+ Surface(
+ name="body1::patch1",
+ private_attribute_sub_components=["body1::patch1"],
+ ),
+ Surface(
+ name="body1::patch2",
+ private_attribute_sub_components=["body1::patch2"],
+ ),
+ Surface(
+ name="body2::patch0",
+ private_attribute_sub_components=["body2::patch0"],
+ ),
+ Surface(
+ name="body3::patch0",
+ private_attribute_sub_components=["body3::patch0"],
+ ),
+ ]
+ ],
+ )
+ elif self.fname == "tester_no_naming.stl":
+ return GeometryEntityInfo(
+ face_ids=["body01_face001", "body01_face002", "body01_face003"],
+ edge_ids=[],
+ face_attribute_names=["faceId"],
+ face_group_tag="faceId",
+ grouped_faces=[
+ [
+ Surface(
+ name="body01_face001",
+ private_attribute_sub_components=["body01_face001"],
+ ),
+ Surface(
+ name="body01_face002",
+ private_attribute_sub_components=["body01_face002"],
+ ),
+ Surface(
+ name="body01_face003",
+ private_attribute_sub_components=["body01_face003"],
+ ),
+ ]
+ ],
+ )
else:
raise ValueError("Invalid file name")
def _populate_registry(self):
self.mesh_unit = LengthType.validate(self._get_meta_data()["mesh_unit"])
- for zone_name in self._get_meta_data()["edges"] if "edges" in self._get_meta_data() else []:
- # pylint: disable=fixme
- # TODO: private_attribute_sub_components is hacked to be just the grouped name,
- # TODO: this should actually be the list of edgeIDs/faceIDs
- self.internal_registry.register(
- Edge(name=zone_name, private_attribute_sub_components=[zone_name])
- )
- for surface_name in (
- self._get_meta_data()["surfaces"] if "surfaces" in self._get_meta_data() else []
- ):
- self.internal_registry.register(
- Surface(name=surface_name, private_attribute_sub_components=[surface_name])
+ if self.snappy:
+ self.internal_registry = self._get_entity_info()._group_entity_by_tag(
+ "face", "faceId", self.internal_registry
)
+ self.snappy_bodies = self._get_entity_info()._group_faces_by_snappy_format()
+ else:
+ for zone_name in (
+ self._get_meta_data()["edges"] if "edges" in self._get_meta_data() else []
+ ):
+ # pylint: disable=fixme
+ # TODO: private_attribute_sub_components is hacked to be just the grouped name,
+ # TODO: this should actually be the list of edgeIDs/faceIDs
+ self.internal_registry.register(
+ Edge(name=zone_name, private_attribute_sub_components=[zone_name])
+ )
+ for surface_name in (
+ self._get_meta_data()["surfaces"] if "surfaces" in self._get_meta_data() else []
+ ):
+ self.internal_registry.register(
+ Surface(name=surface_name, private_attribute_sub_components=[surface_name])
+ )
- def __init__(self, file_name: str):
+ def __init__(self, file_name: str, for_snappy=False):
super().__init__()
self.fname = file_name
+ self.snappy = for_snappy
self._populate_registry()
@@ -329,6 +457,11 @@ def get_rotor_geometry():
return TempGeometry("rotor.csm")
+@pytest.fixture()
+def get_snappy_geometry():
+ return TempGeometry("tester.stl")
+
+
@pytest.fixture()
def airplane_surface_mesh():
my_geometry = TempGeometry("geometry.egads")
@@ -435,7 +568,427 @@ def rotor_surface_mesh():
return param
-def _translate_and_compare(param, mesh_unit, ref_json_file: str):
+@pytest.fixture()
+def snappy_all_defaults():
+ test_geometry = TempGeometry("tester.stl", True)
+ with SI_unit_system:
+ surf_meshing_params = SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=3 * u.mm, max_spacing=4 * u.mm, gap_resolution=1 * u.mm
+ )
+ )
+
+ param = SimulationParams(
+ private_attribute_asset_cache=AssetCache(
+ project_entity_info=test_geometry._get_entity_info(), project_length_unit=1 * u.mm
+ ),
+ meshing=ModularMeshingWorkflow(
+ surface_meshing=surf_meshing_params, zones=[AutomatedFarfield()]
+ ),
+ )
+ return param
+
+
+@pytest.fixture()
+def snappy_basic_refinements():
+ test_geometry = TempGeometry("tester.stl", True)
+ with SI_unit_system:
+ surf_meshing_params = SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=3 * u.mm, max_spacing=4 * u.mm, gap_resolution=1 * u.mm
+ ),
+ base_spacing=3.5 * u.mm,
+ refinements=[
+ SnappyBodyRefinement(
+ gap_resolution=2 * u.mm,
+ min_spacing=5 * u.mm,
+ max_spacing=10 * u.mm,
+ bodies=[
+ test_geometry.snappy_bodies["body1"],
+ test_geometry.snappy_bodies["body3"],
+ ],
+ ),
+ SnappyBodyRefinement(
+ gap_resolution=0.5 * u.mm,
+ min_spacing=1 * u.mm,
+ max_spacing=2 * u.mm,
+ bodies=[test_geometry.snappy_bodies["body2"]],
+ proximity_spacing=0.2 * u.mm,
+ ),
+ SnappyRegionRefinement(
+ min_spacing=20 * u.mm,
+ max_spacing=40 * u.mm,
+ proximity_spacing=3 * u.mm,
+ regions=[
+ test_geometry.snappy_bodies["body0"]["patch0"],
+ test_geometry["body1::patch1"],
+ ],
+ ),
+ SnappySurfaceEdgeRefinement(
+ spacing=4 * u.mm,
+ min_elem=3,
+ included_angle=120 * u.deg,
+ bodies=test_geometry.snappy_bodies["body1"],
+ ),
+ SnappySurfaceEdgeRefinement(
+ spacing=[4 * u.mm],
+ distances=[5 * u.mm],
+ min_elem=3,
+ included_angle=120 * u.deg,
+ regions=[test_geometry.snappy_bodies["body0"]["patch0"]],
+ ),
+ SnappySurfaceEdgeRefinement(
+ spacing=[3 * u.mm, 5e-3 * u.m],
+ distances=[1 * u.mm, 3e-3 * u.m],
+ min_len=6 * u.mm,
+ regions=[test_geometry.snappy_bodies["*"]["patch1"]],
+ bodies=[test_geometry.snappy_bodies["body3"]],
+ retain_on_smoothing=False,
+ ),
+ UniformRefinement(
+ spacing=2 * u.mm,
+ entities=[
+ Box(name="box0", center=[0, 30, 60] * u.mm, size=[20, 30, 40] * u.mm),
+ Cylinder(
+ name="cyl0",
+ axis=[0, 0, 1],
+ center=[10, 20, 30] * u.mm,
+ height=60 * u.mm,
+ outer_radius=20 * u.mm,
+ ),
+ ],
+ ),
+ UniformRefinement(
+ spacing=8 * u.mm,
+ entities=[
+ Cylinder(
+ name="cyl1",
+ axis=[-0.26, 0.45, -0.43],
+ center=[10, 20, 30] * u.mm,
+ height=60 * u.mm,
+ outer_radius=34 * u.mm,
+ )
+ ],
+ ),
+ ],
+ smooth_controls=SnappySmoothControls(),
+ )
+
+ param = SimulationParams(
+ private_attribute_asset_cache=AssetCache(
+ project_entity_info=test_geometry._get_entity_info(), project_length_unit=1 * u.mm
+ ),
+ meshing=ModularMeshingWorkflow(
+ surface_meshing=surf_meshing_params, zones=[AutomatedFarfield()]
+ ),
+ )
+ return param
+
+
+@pytest.fixture()
+def snappy_coupled_refinements():
+ test_geometry = TempGeometry("tester.stl", True)
+ with SI_unit_system:
+ surf_meshing_params = SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=3 * u.mm, max_spacing=4 * u.mm, gap_resolution=1 * u.mm
+ ),
+ base_spacing=5 * u.mm,
+ refinements=[],
+ smooth_controls=SnappySmoothControls(),
+ )
+ vol_meshing_params = BetaVolumeMeshingParams(
+ defaults=BetaVolumeMeshingDefaults(
+ boundary_layer_first_layer_thickness=1 * u.mm, boundary_layer_growth_rate=1.2
+ ),
+ refinements=[
+ UniformRefinement(
+ spacing=2 * u.mm,
+ entities=[
+ Box(name="box0", center=[0, 30, 60] * u.mm, size=[20, 30, 40] * u.mm),
+ Cylinder(
+ name="cyl0",
+ axis=[0, 0, 1],
+ center=[10, 20, 30] * u.mm,
+ height=60 * u.mm,
+ outer_radius=20 * u.mm,
+ ),
+ ],
+ project_to_surface=True,
+ ),
+ UniformRefinement(
+ spacing=8 * u.mm,
+ entities=[
+ Cylinder(
+ name="cyl1",
+ axis=[-0.26, 0.45, -0.43],
+ center=[10, 20, 30] * u.mm,
+ height=60 * u.mm,
+ outer_radius=34 * u.mm,
+ )
+ ],
+ project_to_surface=False,
+ ),
+ ],
+ )
+ param = SimulationParams(
+ private_attribute_asset_cache=AssetCache(
+ project_entity_info=test_geometry._get_entity_info(), project_length_unit=1 * u.mm
+ ),
+ meshing=ModularMeshingWorkflow(
+ surface_meshing=surf_meshing_params,
+ volume_meshing=vol_meshing_params,
+ zones=[SeedpointZone(name="farfield", point_in_mesh=[0, 0, 0] * u.mm)],
+ ),
+ )
+ return param
+
+
+@pytest.fixture()
+def snappy_refinements_multiple_regions():
+ test_geometry = TempGeometry("tester.stl", True)
+ with SI_unit_system:
+ surf_meshing_params = SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=2.999999992 * u.mm, max_spacing=4 * u.mm, gap_resolution=1 * u.mm
+ ),
+ base_spacing=3 * u.mm,
+ refinements=[
+ SnappyRegionRefinement(
+ min_spacing=20 * u.mm,
+ max_spacing=40 * u.mm,
+ proximity_spacing=3 * u.mm,
+ regions=[
+ test_geometry["body1::patch0"],
+ test_geometry.snappy_bodies["body1"]["patch1"],
+ test_geometry["body1::patch2"],
+ ],
+ ),
+ SnappyRegionRefinement(
+ min_spacing=10 * u.mm, max_spacing=40 * u.mm, regions=test_geometry["body0::*"]
+ ),
+ SnappyRegionRefinement(
+ min_spacing=5 * u.mm,
+ max_spacing=40 * u.mm,
+ regions=[
+ test_geometry.snappy_bodies["body2"]["*"],
+ test_geometry["body3::patch0"],
+ ],
+ ),
+ SnappySurfaceEdgeRefinement(
+ spacing=4 * u.mm,
+ min_elem=3,
+ included_angle=120 * u.deg,
+ regions=[test_geometry["body0::patch0"], test_geometry["body0::patch1"]],
+ retain_on_smoothing=False,
+ ),
+ ],
+ smooth_controls=SnappySmoothControls(),
+ )
+
+ param = SimulationParams(
+ private_attribute_asset_cache=AssetCache(
+ project_entity_info=test_geometry._get_entity_info(), project_length_unit=1 * u.mm
+ ),
+ meshing=ModularMeshingWorkflow(
+ surface_meshing=surf_meshing_params, zones=[AutomatedFarfield()]
+ ),
+ )
+ return param
+
+
+@pytest.fixture()
+def snappy_refinements_no_regions():
+ test_geometry = TempGeometry("tester_no_naming.stl", True)
+ with SI_unit_system:
+ surf_meshing_params = SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=3 * u.mm, max_spacing=4 * u.mm, gap_resolution=1 * u.mm
+ ),
+ refinements=[
+ SnappyBodyRefinement(
+ gap_resolution=2 * u.mm,
+ min_spacing=5 * u.mm,
+ max_spacing=10 * u.mm,
+ bodies=[test_geometry.snappy_bodies["body01_face001"]],
+ ),
+ SnappyBodyRefinement(
+ gap_resolution=0.5 * u.mm,
+ min_spacing=1 * u.mm,
+ max_spacing=2 * u.mm,
+ bodies=[test_geometry.snappy_bodies["body01_face002"]],
+ proximity_spacing=0.2 * u.mm,
+ ),
+ SnappySurfaceEdgeRefinement(
+ spacing=4 * u.mm,
+ min_elem=3,
+ included_angle=120 * u.deg,
+ bodies=[test_geometry.snappy_bodies["body01_face003"]],
+ ),
+ ],
+ smooth_controls=SnappySmoothControls(),
+ )
+
+ param = SimulationParams(
+ private_attribute_asset_cache=AssetCache(
+ project_entity_info=test_geometry._get_entity_info(), project_length_unit=1 * u.mm
+ ),
+ meshing=ModularMeshingWorkflow(
+ surface_meshing=surf_meshing_params,
+ zones=[SeedpointZone(name="fluid", point_in_mesh=[0, 0, 0] * u.m)],
+ ),
+ )
+ return param
+
+
+@pytest.fixture()
+def snappy_settings():
+ test_geometry = TempGeometry("tester.stl", True)
+ with SI_unit_system:
+ surf_meshing_params = SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=3 * u.mm, max_spacing=4 * u.mm, gap_resolution=1 * u.mm
+ ),
+ quality_metrics=SnappyQualityMetrics(
+ max_non_ortho=55 * u.deg,
+ max_boundary_skewness=30 * u.deg,
+ max_internal_skewness=70 * u.deg,
+ max_concave=20 * u.deg,
+ min_vol=1e-2,
+ min_tet_quality=0.15,
+ min_area=2 * u.mm * u.mm,
+ min_twist=0.3,
+ min_determinant=0.5,
+ min_vol_ratio=0.1,
+ min_face_weight=0.3,
+ min_triangle_twist=0.1,
+ n_smooth_scale=6,
+ error_reduction=0.4,
+ min_vol_collapse_ratio=0.5,
+ ),
+ snap_controls=SnappySnapControls(
+ n_smooth_patch=5,
+ tolerance=4,
+ n_solve_iter=20,
+ n_relax_iter=2,
+ n_feature_snap_iter=10,
+ multi_region_feature_snap=False,
+ strict_region_snap=True,
+ ),
+ castellated_mesh_controls=SnappyCastellatedMeshControls(
+ resolve_feature_angle=10 * u.deg, n_cells_between_levels=3, min_refinement_cells=50
+ ),
+ smooth_controls=SnappySmoothControls(lambda_factor=0.3, mu_factor=0.31, iterations=5),
+ )
+
+ param = SimulationParams(
+ private_attribute_asset_cache=AssetCache(
+ project_entity_info=test_geometry._get_entity_info(), project_length_unit=1 * u.mm
+ ),
+ meshing=ModularMeshingWorkflow(
+ surface_meshing=surf_meshing_params,
+ zones=[
+ SeedpointZone(name="fluid", point_in_mesh=[0, 0, 0] * u.m),
+ SeedpointZone(name="solid", point_in_mesh=[0.001, 0.002, 0.003] * u.m),
+ ],
+ ),
+ )
+ return param
+
+
+@pytest.fixture()
+def snappy_settings_off_position():
+ test_geometry = TempGeometry("tester.stl", True)
+ with SI_unit_system:
+ surf_meshing_params = SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=3 * u.mm, max_spacing=4 * u.mm, gap_resolution=1 * u.mm
+ ),
+ quality_metrics=SnappyQualityMetrics(
+ max_non_ortho=None,
+ max_boundary_skewness=None,
+ max_internal_skewness=None,
+ max_concave=None,
+ min_vol=None,
+ min_tet_quality=None,
+ min_area=None,
+ min_twist=None,
+ min_determinant=None,
+ min_vol_ratio=None,
+ min_face_weight=None,
+ min_triangle_twist=None,
+ n_smooth_scale=None,
+ error_reduction=None,
+ min_vol_collapse_ratio=None,
+ ),
+ snap_controls=SnappySnapControls(
+ n_smooth_patch=5,
+ tolerance=4,
+ n_solve_iter=20,
+ n_relax_iter=2,
+ n_feature_snap_iter=10,
+ multi_region_feature_snap=False,
+ strict_region_snap=True,
+ ),
+ castellated_mesh_controls=SnappyCastellatedMeshControls(
+ resolve_feature_angle=10 * u.deg, n_cells_between_levels=3, min_refinement_cells=50
+ ),
+ smooth_controls=SnappySmoothControls(
+ lambda_factor=None, mu_factor=None, iterations=None
+ ),
+ )
+
+ param = SimulationParams(
+ private_attribute_asset_cache=AssetCache(
+ project_entity_info=test_geometry._get_entity_info(), project_length_unit=1 * u.mm
+ ),
+ meshing=ModularMeshingWorkflow(
+ surface_meshing=surf_meshing_params,
+ zones=[
+ SeedpointZone(name="fluid", point_in_mesh=[0, 0, 0] * u.m),
+ SeedpointZone(name="solid", point_in_mesh=[0.001, 0.002, 0.003] * u.m),
+ ],
+ ),
+ )
+ return param
+
+
+def deep_sort_lists(obj):
+ """
+ Recursively sort all lists in a JSON-like object to ensure consistent ordering.
+
+ Args:
+ obj: Any JSON-like object (dict, list, str, int, float, bool, None)
+
+ Returns:
+ A new object with all lists sorted
+ """
+ if isinstance(obj, dict):
+ return {k: deep_sort_lists(v) for k, v in sorted(obj.items())}
+ elif isinstance(obj, list):
+ # Sort the list and recursively sort its elements
+ sorted_items = [deep_sort_lists(item) for item in obj]
+
+ # Create a stable sorting key that works for complex nested structures
+ def sort_key(item):
+ if isinstance(item, dict):
+ # For dictionaries, create a canonical string representation
+ return json.dumps(item, sort_keys=True, separators=(",", ":"))
+ elif isinstance(item, list):
+ # For lists, create a canonical string representation
+ return json.dumps(item, sort_keys=True, separators=(",", ":"))
+ else:
+ # For primitives, use string representation
+ return str(item)
+
+ return sorted(sorted_items, key=sort_key)
+ else:
+ return obj
+
+
+def _translate_and_compare(param, mesh_unit, ref_json_file: str, atol=1e-15):
+ param, err = validate_params_with_context(param, "Geometry", "SurfaceMesh")
+ print(err)
translated = get_surface_meshing_json(param, mesh_unit=mesh_unit)
with open(
os.path.join(
@@ -443,7 +996,11 @@ def _translate_and_compare(param, mesh_unit, ref_json_file: str):
)
) as fh:
ref_dict = json.load(fh)
- assert compare_values(ref_dict, translated)
+
+ ref_dict, translated = deep_sort_lists(ref_dict), deep_sort_lists(translated)
+ # check if everything is seriazable
+ json.dumps(translated)
+ assert compare_values(ref_dict, translated, atol=atol)
def test_om6wing_tutorial(
@@ -486,6 +1043,54 @@ def test_rotor_surface_mesh(get_rotor_geometry, rotor_surface_mesh):
)
+def test_snappy_default(get_snappy_geometry, snappy_all_defaults):
+ _translate_and_compare(
+ snappy_all_defaults, get_snappy_geometry.mesh_unit, "default_snappy.json"
+ )
+
+
+def test_snappy_basic(get_snappy_geometry, snappy_basic_refinements):
+ _translate_and_compare(
+ snappy_basic_refinements,
+ get_snappy_geometry.mesh_unit,
+ "snappy_basic_refinements.json",
+ atol=1e-6,
+ )
+
+
+def test_snappy_coupled(get_snappy_geometry, snappy_coupled_refinements):
+ _translate_and_compare(
+ snappy_coupled_refinements,
+ get_snappy_geometry.mesh_unit,
+ "snappy_coupled_refinements.json",
+ atol=1e-6,
+ )
+
+
+def test_snappy_multiple_regions(get_snappy_geometry, snappy_refinements_multiple_regions):
+ _translate_and_compare(
+ snappy_refinements_multiple_regions,
+ get_snappy_geometry.mesh_unit,
+ "snappy_refinements_multiple_regions.json",
+ )
+
+
+def test_snappy_settings(get_snappy_geometry, snappy_settings):
+ _translate_and_compare(snappy_settings, get_snappy_geometry.mesh_unit, "snappy_settings.json")
+
+
+def test_snappy_settings_off_position(get_snappy_geometry, snappy_settings_off_position):
+ _translate_and_compare(
+ snappy_settings_off_position, get_snappy_geometry.mesh_unit, "snappy_settings_off_pos.json"
+ )
+
+
+def test_snappy_no_refinements(get_snappy_geometry, snappy_refinements_no_regions):
+ _translate_and_compare(
+ snappy_refinements_no_regions, get_snappy_geometry.mesh_unit, "snappy_no_regions.json"
+ )
+
+
def test_gai_surface_mesher_refinements():
geometry = Geometry.from_local_storage(
geometry_id="geo-e5c01a98-2180-449e-b255-d60162854a83",
@@ -559,3 +1164,56 @@ def test_gai_surface_mesher_refinements():
1 * u.m,
"gai_surface_mesher.json",
)
+
+
+def test_gai_translator_hashing_ignores_id():
+ """Test that hash calculation ignores private_attribute_id fields."""
+
+ hashes = []
+ json_dicts = []
+
+ # Create the same configuration twice in a loop
+ # Each iteration generates different UUIDs for entities with private_attribute_id
+ for i in range(2):
+ with SI_unit_system:
+ # Cylinder has private_attribute_id with generate_uuid factory
+ cylinder = Cylinder(
+ name="test_cylinder",
+ center=[0, 0, 0] * u.m,
+ axis=[0, 0, 1],
+ height=10 * u.m,
+ outer_radius=5 * u.m,
+ )
+
+ params = SimulationParams(
+ meshing=MeshingParams(
+ defaults=MeshingDefaults(
+ surface_max_edge_length=0.2,
+ ),
+ refinements=[
+ UniformRefinement(
+ name="cylinder_refinement", entities=[cylinder], spacing=0.1 * u.m
+ )
+ ],
+ )
+ )
+
+ # Export to dict
+ params_dict = params.model_dump(mode="json")
+ json_dicts.append(params_dict)
+
+ # Calculate hash
+ hash_value = SimulationParams._calculate_hash(params_dict)
+ hashes.append(hash_value)
+
+ # Verify JSONs are different (due to different UUIDs)
+ json_str_0 = json.dumps(json_dicts[0], sort_keys=True)
+ json_str_1 = json.dumps(json_dicts[1], sort_keys=True)
+ assert (
+ json_str_0 != json_str_1
+ ), "JSON strings should differ due to different private_attribute_id (UUID) values"
+
+ # Verify hashes are identical (UUID ignored in hash calculation)
+ assert (
+ hashes[0] == hashes[1]
+ ), f"Hashes should be identical despite different UUIDs:\n Hash 1: {hashes[0]}\n Hash 2: {hashes[1]}"
diff --git a/tests/simulation/translator/test_volume_meshing_translator.py b/tests/simulation/translator/test_volume_meshing_translator.py
index 02a73024b..a1c72c298 100644
--- a/tests/simulation/translator/test_volume_meshing_translator.py
+++ b/tests/simulation/translator/test_volume_meshing_translator.py
@@ -6,18 +6,34 @@
BoundaryLayer,
PassiveSpacing,
)
-from flow360.component.simulation.meshing_param.params import (
+from flow360.component.simulation.meshing_param.meshing_specs import (
+ BetaVolumeMeshingDefaults,
MeshingDefaults,
+ SnappySurfaceMeshingDefaults,
+)
+from flow360.component.simulation.meshing_param.params import (
+ BetaVolumeMeshingParams,
MeshingParams,
+ ModularMeshingWorkflow,
+ SnappySurfaceMeshingParams,
)
from flow360.component.simulation.meshing_param.volume_params import (
AutomatedFarfield,
AxisymmetricRefinement,
RotationCylinder,
+ RotationVolume,
+ StructuredBoxRefinement,
UniformRefinement,
UserDefinedFarfield,
)
-from flow360.component.simulation.primitives import Box, CustomVolume, Cylinder, Surface
+from flow360.component.simulation.primitives import (
+ AxisymmetricBody,
+ Box,
+ CustomVolume,
+ Cylinder,
+ SeedpointZone,
+ Surface,
+)
from flow360.component.simulation.simulation_params import SimulationParams
from flow360.component.simulation.translator.volume_meshing_translator import (
get_volume_meshing_json,
@@ -98,7 +114,12 @@ def get_test_param():
center=(0, 5, 0),
)
cylinder_3 = Cylinder(
- name="3", inner_radius=1.5, outer_radius=2, height=2, axis=(0, 1, 0), center=(0, -5, 0)
+ name="3",
+ inner_radius=1.5,
+ outer_radius=2,
+ height=2,
+ axis=(0, 1, 0),
+ center=(0, -5, 0),
)
cylinder_outer = Cylinder(
name="outer",
@@ -108,6 +129,20 @@ def get_test_param():
axis=(1, 0, 0),
center=(0, 0, 0),
)
+ cone_frustum = AxisymmetricBody(
+ name="cone",
+ axis=(1, 0, 1),
+ center=(0, 0, 0),
+ profile_curve=[(-1, 0), (-1, 1), (1, 2), (1, 0)],
+ )
+
+ porous_medium = Box.from_principal_axes(
+ name="porousRegion",
+ center=(0, 1, 1),
+ size=(1, 2, 1),
+ axes=((2, 2, 0), (-2, 2, 0)),
+ )
+
param = SimulationParams(
meshing=MeshingParams(
refinement_factor=1.45,
@@ -134,6 +169,12 @@ def get_test_param():
spacing_radial=0.2,
spacing_circumferential=20 * u.cm,
),
+ StructuredBoxRefinement(
+ entities=[porous_medium],
+ spacing_axis1=7.5 * u.cm,
+ spacing_axis2=10 * u.cm,
+ spacing_normal=15 * u.cm,
+ ),
PassiveSpacing(entities=[Surface(name="passive1")], type="projected"),
PassiveSpacing(entities=[Surface(name="passive2")], type="unchanged"),
BoundaryLayer(
@@ -143,12 +184,209 @@ def get_test_param():
),
],
volume_zones=[
+ CustomVolume(
+ name="custom_volume-1",
+ boundaries=[
+ Surface(name="interface1"),
+ Surface(name="interface2"),
+ ],
+ ),
+ RotationVolume(
+ name="we_do_not_use_this_anyway",
+ entities=inner_cylinder,
+ spacing_axial=20 * u.cm,
+ spacing_radial=0.2,
+ spacing_circumferential=20 * u.cm,
+ enclosed_entities=[
+ Surface(name="hub"),
+ Surface(name="blade1"),
+ Surface(name="blade2"),
+ Surface(name="blade3"),
+ cone_frustum,
+ ],
+ ),
+ RotationVolume(
+ entities=mid_cylinder,
+ spacing_axial=20 * u.cm,
+ spacing_radial=0.2,
+ spacing_circumferential=20 * u.cm,
+ enclosed_entities=[inner_cylinder],
+ ),
+ RotationVolume(
+ entities=cylinder_2,
+ spacing_axial=20 * u.cm,
+ spacing_radial=0.2,
+ spacing_circumferential=20 * u.cm,
+ enclosed_entities=[rotor_disk_cylinder, porous_medium],
+ ),
+ RotationVolume(
+ entities=cylinder_3,
+ spacing_axial=20 * u.cm,
+ spacing_radial=0.2,
+ spacing_circumferential=20 * u.cm,
+ ),
+ RotationVolume(
+ entities=cylinder_outer,
+ spacing_axial=40 * u.cm,
+ spacing_radial=0.4,
+ spacing_circumferential=40 * u.cm,
+ enclosed_entities=[
+ mid_cylinder,
+ rotor_disk_cylinder,
+ cylinder_2,
+ cylinder_3,
+ ],
+ ),
+ RotationVolume(
+ entities=cone_frustum,
+ spacing_axial=40 * u.cm,
+ spacing_radial=0.4,
+ spacing_circumferential=20 * u.cm,
+ ),
+ ],
+ ),
+ private_attribute_asset_cache=AssetCache(use_inhouse_mesher=True),
+ )
+ return param
+
+
+@pytest.fixture()
+def get_test_param_automated_farfield():
+ with SI_unit_system:
+
+ param = SimulationParams(
+ meshing=MeshingParams(
+ refinement_factor=1.45,
+ defaults=MeshingDefaults(
+ boundary_layer_first_layer_thickness=1.35e-06 * u.m,
+ boundary_layer_growth_rate=1 + 0.04,
+ ),
+ refinements=[
+ PassiveSpacing(entities=[Surface(name="passive1")], type="projected"),
+ PassiveSpacing(entities=[Surface(name="passive2")], type="unchanged"),
+ BoundaryLayer(
+ entities=[Surface(name="boundary1")],
+ first_layer_thickness=0.5 * u.m,
+ growth_rate=1.3,
+ ),
+ ],
+ volume_zones=[AutomatedFarfield()],
+ ),
+ private_attribute_asset_cache=AssetCache(use_inhouse_mesher=True),
+ )
+ return param
+
+
+@pytest.fixture()
+def get_test_param_modular():
+ with SI_unit_system:
+ base_cylinder = Cylinder(
+ name="cylinder_1",
+ outer_radius=1.1,
+ height=2 * u.m,
+ axis=(0, 1, 0),
+ center=(0.7, -1.0, 0),
+ )
+ rotor_disk_cylinder = Cylinder(
+ name="enclosed",
+ outer_radius=1.1,
+ height=0.15 * u.m,
+ axis=(0, 1, 0),
+ center=(0.7, -1.0, 0),
+ )
+ inner_cylinder = Cylinder(
+ name="inner",
+ outer_radius=0.75,
+ height=0.5,
+ axis=(0, 0, 1),
+ center=(0, 0, 0),
+ )
+ mid_cylinder = Cylinder(
+ name="mid",
+ outer_radius=2,
+ height=2,
+ axis=(0, 1, 0),
+ center=(0, 0, 0),
+ )
+ cylinder_2 = Cylinder(
+ name="2",
+ outer_radius=2,
+ height=2,
+ axis=(0, 1, 0),
+ center=(0, 5, 0),
+ )
+ cylinder_3 = Cylinder(
+ name="3", inner_radius=1.5, outer_radius=2, height=2, axis=(0, 1, 0), center=(0, -5, 0)
+ )
+ cylinder_outer = Cylinder(
+ name="outer",
+ inner_radius=0,
+ outer_radius=8,
+ height=6,
+ axis=(1, 0, 0),
+ center=(0, 0, 0),
+ )
+ cone_frustum = AxisymmetricBody(
+ name="cone",
+ axis=(1, 0, 1),
+ center=(0, 0, 0),
+ profile_curve=[(-1, 0), (-1, 1), (1, 2), (1, 0)],
+ )
+
+ porous_medium = Box.from_principal_axes(
+ name="porousRegion",
+ center=(0, 1, 1),
+ size=(1, 2, 1),
+ axes=((2, 2, 0), (-2, 2, 0)),
+ )
+ param = SimulationParams(
+ meshing=ModularMeshingWorkflow(
+ volume_meshing=BetaVolumeMeshingParams(
+ defaults=BetaVolumeMeshingDefaults(
+ boundary_layer_first_layer_thickness=1.35e-06 * u.m,
+ boundary_layer_growth_rate=1 + 0.04,
+ ),
+ refinement_factor=1.45,
+ refinements=[
+ UniformRefinement(
+ entities=[
+ base_cylinder,
+ Box.from_principal_axes(
+ name="MyBox",
+ center=(0, 1, 2),
+ size=(4, 5, 6),
+ axes=((2, 2, 0), (-2, 2, 0)),
+ ),
+ ],
+ spacing=7.5 * u.cm,
+ ),
+ AxisymmetricRefinement(
+ entities=[rotor_disk_cylinder],
+ spacing_axial=20 * u.cm,
+ spacing_radial=0.2,
+ spacing_circumferential=20 * u.cm,
+ ),
+ StructuredBoxRefinement(
+ entities=[porous_medium],
+ spacing_axis1=7.5 * u.cm,
+ spacing_axis2=10 * u.cm,
+ spacing_normal=15 * u.cm,
+ ),
+ PassiveSpacing(entities=[Surface(name="passive1")], type="projected"),
+ PassiveSpacing(entities=[Surface(name="passive2")], type="unchanged"),
+ BoundaryLayer(
+ entities=[Surface(name="boundary1")],
+ first_layer_thickness=0.5 * u.m,
+ growth_rate=1.3,
+ ),
+ ],
+ ),
+ zones=[
CustomVolume(
name="custom_volume-1",
boundaries=[Surface(name="interface1"), Surface(name="interface2")],
),
- UserDefinedFarfield(),
- RotationCylinder(
+ RotationVolume(
name="we_do_not_use_this_anyway",
entities=inner_cylinder,
spacing_axial=20 * u.cm,
@@ -159,29 +397,30 @@ def get_test_param():
Surface(name="blade1"),
Surface(name="blade2"),
Surface(name="blade3"),
+ cone_frustum,
],
),
- RotationCylinder(
+ RotationVolume(
entities=mid_cylinder,
spacing_axial=20 * u.cm,
spacing_radial=0.2,
spacing_circumferential=20 * u.cm,
enclosed_entities=[inner_cylinder],
),
- RotationCylinder(
+ RotationVolume(
entities=cylinder_2,
spacing_axial=20 * u.cm,
spacing_radial=0.2,
spacing_circumferential=20 * u.cm,
- enclosed_entities=[rotor_disk_cylinder],
+ enclosed_entities=[rotor_disk_cylinder, porous_medium],
),
- RotationCylinder(
+ RotationVolume(
entities=cylinder_3,
spacing_axial=20 * u.cm,
spacing_radial=0.2,
spacing_circumferential=20 * u.cm,
),
- RotationCylinder(
+ RotationVolume(
entities=cylinder_outer,
spacing_axial=40 * u.cm,
spacing_radial=0.4,
@@ -193,6 +432,12 @@ def get_test_param():
cylinder_3,
],
),
+ RotationVolume(
+ entities=cone_frustum,
+ spacing_axial=40 * u.cm,
+ spacing_radial=0.4,
+ spacing_circumferential=20 * u.cm,
+ ),
],
),
private_attribute_asset_cache=AssetCache(use_inhouse_mesher=True),
@@ -200,8 +445,37 @@ def get_test_param():
return param
-def test_param_to_json(get_test_param, get_surface_mesh):
- translated = get_volume_meshing_json(get_test_param, get_surface_mesh.mesh_unit)
+@pytest.fixture()
+def get_test_param_w_seedpoints():
+ with SI_unit_system:
+ param = SimulationParams(
+ meshing=ModularMeshingWorkflow(
+ surface_meshing=SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=1, max_spacing=2, gap_resolution=1
+ )
+ ),
+ volume_meshing=BetaVolumeMeshingParams(
+ defaults=BetaVolumeMeshingDefaults(
+ boundary_layer_first_layer_thickness=1.35e-06 * u.m,
+ boundary_layer_growth_rate=1 + 0.04,
+ ),
+ refinement_factor=1.45,
+ refinements=[],
+ ),
+ zones=[
+ SeedpointZone(name="fluid", point_in_mesh=(0, 0, 0)),
+ SeedpointZone(name="radiator", point_in_mesh=(1, 1, 1)),
+ ],
+ ),
+ private_attribute_asset_cache=AssetCache(use_inhouse_mesher=True),
+ )
+ return param
+
+
+def test_param_to_json(get_test_param, get_surface_mesh, get_test_param_modular):
+ translated_standard = get_volume_meshing_json(get_test_param, get_surface_mesh.mesh_unit)
+ translated_modular = get_volume_meshing_json(get_test_param_modular, get_surface_mesh.mesh_unit)
ref_dict = {
"refinementFactor": 1.45,
@@ -214,7 +488,11 @@ def test_param_to_json(get_test_param, get_surface_mesh):
"numBoundaryLayers": -1,
},
"faces": {
- "boundary1": {"firstLayerThickness": 0.5, "type": "aniso", "growthRate": 1.3},
+ "boundary1": {
+ "firstLayerThickness": 0.5,
+ "type": "aniso",
+ "growthRate": 1.3,
+ },
"passive1": {"type": "projectAnisoSpacing"},
"passive2": {"type": "none"},
},
@@ -252,6 +530,7 @@ def test_param_to_json(get_test_param, get_surface_mesh):
"slidingInterfaces": [ # comes from documentation page
{
"name": "inner",
+ "type": "Cylinder",
"innerRadius": 0,
"outerRadius": 0.75,
"thickness": 0.5,
@@ -260,10 +539,17 @@ def test_param_to_json(get_test_param, get_surface_mesh):
"spacingAxial": 0.2,
"spacingRadial": 0.2,
"spacingCircumferential": 0.2,
- "enclosedObjects": ["hub", "blade1", "blade2", "blade3"],
+ "enclosedObjects": [
+ "hub",
+ "blade1",
+ "blade2",
+ "blade3",
+ "slidingInterface-cone",
+ ],
},
{
"name": "mid",
+ "type": "Cylinder",
"innerRadius": 0,
"outerRadius": 2.0,
"thickness": 2.0,
@@ -276,6 +562,7 @@ def test_param_to_json(get_test_param, get_surface_mesh):
},
{
"name": "2",
+ "type": "Cylinder",
"innerRadius": 0,
"outerRadius": 2.0,
"thickness": 2.0,
@@ -284,10 +571,11 @@ def test_param_to_json(get_test_param, get_surface_mesh):
"spacingAxial": 0.2,
"spacingRadial": 0.2,
"spacingCircumferential": 0.2,
- "enclosedObjects": ["rotorDisk-enclosed"],
+ "enclosedObjects": ["rotorDisk-enclosed", "structuredBox-porousRegion"],
},
{
"name": "3",
+ "type": "Cylinder",
"innerRadius": 1.5,
"outerRadius": 2.0,
"thickness": 2.0,
@@ -300,6 +588,7 @@ def test_param_to_json(get_test_param, get_surface_mesh):
},
{
"name": "outer",
+ "type": "Cylinder",
"innerRadius": 0.0,
"outerRadius": 8.0,
"thickness": 6.0,
@@ -315,6 +604,32 @@ def test_param_to_json(get_test_param, get_surface_mesh):
"slidingInterface-3",
],
},
+ {
+ "type": "Axisymmetric",
+ "name": "cone",
+ "axisOfRotation": [0.7071067811865476, 0.0, 0.7071067811865476],
+ "center": [0.0, 0.0, 0.0],
+ "profileCurve": [[-1.0, 0.0], [-1.0, 1.0], [1.0, 2.0], [1.0, 0.0]],
+ "spacingAxial": 0.4,
+ "spacingCircumferential": 0.2,
+ "spacingRadial": 0.4,
+ "enclosedObjects": [],
+ },
+ ],
+ "structuredRegions": [
+ {
+ "name": "porousRegion",
+ "type": "box",
+ "lengthAxis1": 1.0,
+ "lengthAxis2": 2.0,
+ "lengthNormal": 1.0,
+ "axis1": [0.7071067811865476, 0.7071067811865476, 0.0],
+ "axis2": [-0.7071067811865476, 0.7071067811865476, 0.0],
+ "center": [0.0, 1.0, 1.0],
+ "spacingAxis1": 0.075,
+ "spacingAxis2": 0.1,
+ "spacingNormal": 0.15,
+ }
],
"zones": [
{
@@ -324,7 +639,33 @@ def test_param_to_json(get_test_param, get_surface_mesh):
],
}
- assert sorted(translated.items()) == sorted(ref_dict.items())
+ assert sorted(translated_standard.items()) == sorted(ref_dict.items())
+ assert sorted(translated_modular.items()) == sorted(ref_dict.items())
+
+
+def test_param_to_json_automated_farfield(get_test_param_automated_farfield, get_surface_mesh):
+ translated_standard = get_volume_meshing_json(
+ get_test_param_automated_farfield, get_surface_mesh.mesh_unit
+ )
+
+ ref_dict = {
+ "refinementFactor": 1.45,
+ "farfield": {"type": "auto", "planarFaceTolerance": 1e-6},
+ "volume": {
+ "firstLayerThickness": 1.35e-06,
+ "growthRate": 1.04,
+ "gapTreatmentStrength": 0.0,
+ "planarFaceTolerance": 1e-6,
+ "numBoundaryLayers": -1,
+ },
+ "faces": {
+ "boundary1": {"firstLayerThickness": 0.5, "type": "aniso", "growthRate": 1.3},
+ "passive1": {"type": "projectAnisoSpacing"},
+ "passive2": {"type": "none"},
+ },
+ }
+
+ assert sorted(translated_standard.items()) == sorted(ref_dict.items())
def test_user_defined_farfield(get_test_param, get_surface_mesh):
@@ -335,8 +676,32 @@ def test_user_defined_farfield(get_test_param, get_surface_mesh):
volume_zones=[UserDefinedFarfield()],
)
)
+ params_modular = SimulationParams(
+ meshing=ModularMeshingWorkflow(
+ surface_meshing=SnappySurfaceMeshingParams(
+ defaults=SnappySurfaceMeshingDefaults(
+ min_spacing=1, max_spacing=2, gap_resolution=1
+ )
+ ),
+ volume_meshing=BetaVolumeMeshingParams(
+ defaults=BetaVolumeMeshingDefaults(boundary_layer_first_layer_thickness=100),
+ ),
+ zones=[SeedpointZone(point_in_mesh=[0, 0, 0], name="farfield")],
+ )
+ )
translated = get_volume_meshing_json(params, get_surface_mesh.mesh_unit)
- reference = {
+ translated_modular = get_volume_meshing_json(params_modular, get_surface_mesh.mesh_unit)
+ reference_standard = {
+ "refinementFactor": 1.0,
+ "farfield": {"type": "user-defined"},
+ "volume": {
+ "firstLayerThickness": 100.0,
+ "growthRate": 1.2,
+ "gapTreatmentStrength": 0.0,
+ },
+ "faces": {},
+ }
+ reference_snappy_modular = {
"refinementFactor": 1.0,
"farfield": {"type": "user-defined"},
"volume": {
@@ -345,5 +710,38 @@ def test_user_defined_farfield(get_test_param, get_surface_mesh):
"gapTreatmentStrength": 0.0,
},
"faces": {},
+ "zones": [{"name": "farfield", "pointInMesh": [0, 0, 0]}],
}
- assert sorted(translated.items()) == sorted(reference.items())
+ assert sorted(translated.items()) == sorted(reference_standard.items())
+ assert sorted(translated_modular.items()) == sorted(reference_snappy_modular.items())
+
+
+def test_seedpoint_zones(get_test_param_w_seedpoints, get_surface_mesh):
+ translated_modular = get_volume_meshing_json(
+ get_test_param_w_seedpoints, get_surface_mesh.mesh_unit
+ )
+
+ reference = {
+ "refinementFactor": 1.45,
+ "farfield": {"type": "user-defined"},
+ "volume": {
+ "firstLayerThickness": 1.35e-06,
+ "growthRate": 1.04,
+ "gapTreatmentStrength": 0.0,
+ "planarFaceTolerance": 1e-6,
+ "numBoundaryLayers": -1,
+ },
+ "faces": {},
+ "zones": [
+ {
+ "name": "fluid",
+ "pointInMesh": [0, 0, 0],
+ },
+ {
+ "name": "radiator",
+ "pointInMesh": [1, 1, 1],
+ },
+ ],
+ }
+
+ assert sorted(translated_modular.items()) == sorted(reference.items())
diff --git a/tests/surface_forces_by_boundary b/tests/surface_forces_by_boundary
new file mode 100644
index 000000000..5454a890b
--- /dev/null
+++ b/tests/surface_forces_by_boundary
@@ -0,0 +1,3 @@
+,physical_step,pseudo_step,Wall body 1 and 2_CL,Wall body 1 and 2_CD,Wall body 1 and 2_CFx,Wall body 1 and 2_CFy,Wall body 1 and 2_CFz,Wall body 1 and 2_CMx,Wall body 1 and 2_CMy,Wall body 1 and 2_CMz,Wall body 1 and 2_CLPressure,Wall body 1 and 2_CDPressure,Wall body 1 and 2_CFxPressure,Wall body 1 and 2_CFyPressure,Wall body 1 and 2_CFzPressure,Wall body 1 and 2_CMxPressure,Wall body 1 and 2_CMyPressure,Wall body 1 and 2_CMzPressure,Wall body 1 and 2_CLSkinFriction,Wall body 1 and 2_CDSkinFriction,Wall body 1 and 2_CFxSkinFriction,Wall body 1 and 2_CFySkinFriction,Wall body 1 and 2_CFzSkinFriction,Wall body 1 and 2_CMxSkinFriction,Wall body 1 and 2_CMySkinFriction,Wall body 1 and 2_CMzSkinFriction,Freestream_CL,Freestream_CD,Freestream_CFx,Freestream_CFy,Freestream_CFz,Freestream_CMx,Freestream_CMy,Freestream_CMz,Freestream_CLPressure,Freestream_CDPressure,Freestream_CFxPressure,Freestream_CFyPressure,Freestream_CFzPressure,Freestream_CMxPressure,Freestream_CMyPressure,Freestream_CMzPressure,Freestream_CLSkinFriction,Freestream_CDSkinFriction,Freestream_CFxSkinFriction,Freestream_CFySkinFriction,Freestream_CFzSkinFriction,Freestream_CMxSkinFriction,Freestream_CMySkinFriction,Freestream_CMzSkinFriction,Wall body3_CL,Wall body3_CD,Wall body3_CFx,Wall body3_CFy,Wall body3_CFz,Wall body3_CMx,Wall body3_CMy,Wall body3_CMz,Wall body3_CLPressure,Wall body3_CDPressure,Wall body3_CFxPressure,Wall body3_CFyPressure,Wall body3_CFzPressure,Wall body3_CMxPressure,Wall body3_CMyPressure,Wall body3_CMzPressure,Wall body3_CLSkinFriction,Wall body3_CDSkinFriction,Wall body3_CFxSkinFriction,Wall body3_CFySkinFriction,Wall body3_CFzSkinFriction,Wall body3_CMxSkinFriction,Wall body3_CMySkinFriction,Wall body3_CMzSkinFriction,totalCL,totalCD,totalCFx,totalCFy,totalCFz,totalCMx,totalCMy,totalCMz,totalCLPressure,totalCDPressure,totalCFxPressure,totalCFyPressure,totalCFzPressure,totalCMxPressure,totalCMyPressure,totalCMzPressure,totalCLSkinFriction,totalCDSkinFriction,totalCFxSkinFriction,totalCFySkinFriction,totalCFzSkinFriction,totalCMxSkinFriction,totalCMySkinFriction,totalCMzSkinFriction
+0,0,0,302.0002,304.0002,306.0002,308.0002,310.0002,312.0002,314.0002,316.0002,318.0002,320.0002,322.0002,324.0002,326.0002,328.0002,330.0002,332.0002,334.0002,336.0002,338.0002,340.0002,342.0002,344.0002,346.0002,348.0002,603.0002999999999,606.0002999999999,609.0002999999999,612.0002999999999,615.0002999999999,618.0002999999999,621.0002999999999,624.0002999999999,627.0002999999999,630.0002999999999,633.0002999999999,636.0002999999999,639.0002999999999,642.0002999999999,645.0002999999999,648.0002999999999,651.0002999999999,654.0002999999999,657.0002999999999,660.0002999999999,663.0002999999999,666.0002999999999,669.0002999999999,672.0002999999999,301.0001,302.0001,303.0001,304.0001,305.0001,306.0001,307.0001,308.0001,309.0001,310.0001,311.0001,312.0001,313.0001,314.0001,315.0001,316.0001,317.0001,318.0001,319.0001,320.0001,321.0001,322.0001,323.0001,324.0001,1206.0005999999998,1212.0005999999998,1218.0005999999998,1224.0005999999998,1230.0005999999998,1236.0005999999998,1242.0005999999998,1248.0005999999998,1254.0005999999998,1260.0005999999998,1266.0005999999998,1272.0005999999998,1278.0005999999998,1284.0005999999998,1290.0005999999998,1296.0005999999998,1302.0005999999998,1308.0005999999998,1314.0005999999998,1320.0005999999998,1326.0005999999998,1332.0005999999998,1338.0005999999998,1344.0005999999998
+1,0,10,302.0004,304.0004,306.0004,308.0004,310.0004,312.0004,314.0004,316.0004,318.0004,320.0004,322.0004,324.0004,326.0004,328.0004,330.0004,332.0004,334.0004,336.0004,338.0004,340.0004,342.0004,344.0004,346.0004,348.0004,603.0006000000001,606.0006000000001,609.0006000000001,612.0006000000001,615.0006000000001,618.0006000000001,621.0006000000001,624.0006000000001,627.0006000000001,630.0006000000001,633.0006000000001,636.0006000000001,639.0006000000001,642.0006000000001,645.0006000000001,648.0006000000001,651.0006000000001,654.0006000000001,657.0006000000001,660.0006000000001,663.0006000000001,666.0006000000001,669.0006000000001,672.0006000000001,301.0002,302.0002,303.0002,304.0002,305.0002,306.0002,307.0002,308.0002,309.0002,310.0002,311.0002,312.0002,313.0002,314.0002,315.0002,316.0002,317.0002,318.0002,319.0002,320.0002,321.0002,322.0002,323.0002,324.0002,1206.0012000000002,1212.0012000000002,1218.0012000000002,1224.0012000000002,1230.0012000000002,1236.0012000000002,1242.0012000000002,1248.0012000000002,1254.0012000000002,1260.0012000000002,1266.0012000000002,1272.0012000000002,1278.0012000000002,1284.0012000000002,1290.0012000000002,1296.0012000000002,1302.0012000000002,1308.0012000000002,1314.0012000000002,1320.0012000000002,1326.0012000000002,1332.0012000000002,1338.0012000000002,1344.0012000000002
diff --git a/tests/test_current_flow360_version.py b/tests/test_current_flow360_version.py
index d10c58d5c..dab5320b8 100644
--- a/tests/test_current_flow360_version.py
+++ b/tests/test_current_flow360_version.py
@@ -2,4 +2,4 @@
def test_version():
- assert __version__ == "25.7.4b0"
+ assert __version__ == "25.8.0b3"
diff --git a/tests/test_results.py b/tests/test_results.py
index 1c2b1c21a..9421ee5f5 100644
--- a/tests/test_results.py
+++ b/tests/test_results.py
@@ -30,7 +30,52 @@
from flow360.component.simulation.simulation_params import SimulationParams
from flow360.component.simulation.utils import model_attribute_unlock
-log.set_logging_level("DEBUG")
+# log.set_logging_level("DEBUG")
+
+
+def compare_dataframes_with_tolerance(
+ df1: pandas.DataFrame, df2: pandas.DataFrame, rtol: float = 1e-8, atol: float = 1e-8
+) -> None:
+ """Compare two dataframes with numerical tolerance.
+
+ Args:
+ df1: First dataframe to compare
+ df2: Second dataframe (reference) to compare against
+ rtol: Relative tolerance for numerical comparison (default: 1e-5)
+ atol: Absolute tolerance for numerical comparison (default: 1e-8)
+
+ Raises:
+ AssertionError: If dataframes differ beyond tolerance
+ """
+ # Check that columns match
+ assert set(df1.columns) == set(df2.columns), (
+ f"Column mismatch:\n"
+ f" df1 columns: {sorted(df1.columns)}\n"
+ f" df2 columns: {sorted(df2.columns)}\n"
+ f" Missing in df1: {set(df2.columns) - set(df1.columns)}\n"
+ f" Missing in df2: {set(df1.columns) - set(df2.columns)}"
+ )
+
+ # Check that shape matches
+ assert df1.shape == df2.shape, f"Shape mismatch: {df1.shape} vs {df2.shape}"
+
+ # Reorder columns to match
+ df1 = df1[df2.columns]
+
+ # Compare each column
+ for col in df2.columns:
+ if np.issubdtype(df1[col].dtype, np.number) and np.issubdtype(df2[col].dtype, np.number):
+ # Numerical comparison with tolerance
+ np.testing.assert_allclose(
+ df1[col].values,
+ df2[col].values,
+ rtol=rtol,
+ atol=atol,
+ err_msg=f"Column '{col}' values differ beyond tolerance",
+ )
+ else:
+ # Exact comparison for non-numerical columns
+ assert df1[col].equals(df2[col]), f"Column '{col}' values differ"
@pytest.fixture(autouse=True)
@@ -232,6 +277,7 @@ def test_include_filter_with_suffixes():
"boundary_a_a_B",
]
result = _filter_headers_by_prefix(headers, include=["boundary_a"], suffixes=["A", "B"])
+ result = _filter_headers_by_prefix(headers, include=["boundary_a"], suffixes=["A", "B"])
assert sorted(result) == sorted(["boundary_a_A", "boundary_a_B"])
result = _filter_headers_by_prefix(headers, exclude=["boundary_a_a"], suffixes=["A", "B"])
@@ -275,27 +321,6 @@ def test_no_suffixes_provided_headers_with_underscore():
assert sorted(result) == sorted(["abc_def"])
-def test_no_suffixes_provided_no_include_filter():
- headers = [
- "abc_def",
- "xyz_123",
- "nounderscore",
- "abc_xyz",
- ]
- result = _filter_headers_by_prefix(headers)
- assert sorted(result) == sorted(
- [
- "abc_def",
- "xyz_123",
- "nounderscore",
- "abc_xyz",
- ]
- )
-
-
-test_no_suffixes_provided_no_include_filter()
-
-
def test_empty_headers():
headers: List[str] = []
result = _filter_headers_by_prefix(headers, include=["anything"], suffixes=["A", "B"])
@@ -485,7 +510,7 @@ def test_y_sectional_results(mock_id, mock_response):
boundaries = ["blk-1/fuselage", "blk-1/leftWing", "blk-1/rightWing"]
variables = ["CFx_per_span", "CFz_per_span", "CMy_per_span"]
- x_columns = ["Y", "stride"]
+ x_columns = ["Y"]
total = [f"total{postfix}" for postfix in variables]
all_headers = (
@@ -622,8 +647,6 @@ def validate_grouped_results(grouped_data, entity_group, flat_boundary_list, val
surface_forces = case.results.surface_forces
surface_forces_by_boundary = surface_forces.by_boundary_condition(params=params)
- surface_forces_by_boundary.as_dataframe().to_csv("surface_forces_by_boundary")
-
ref_entity_group_by_boundary = {
"Wall body 1 and 2": ["body00001", "body00002"],
"Wall body3": ["body00003"],
@@ -648,3 +671,116 @@ def validate_grouped_results(grouped_data, entity_group, flat_boundary_list, val
flat_boundary_list=("body00001", "body00002", "body00003"),
valid_names=("geo-11321727-9bb1-4fd5-b88d-19f360fb2149_box.csm"),
)
+
+
+@pytest.mark.usefixtures("s3_download_override")
+def test_force_distribution_result(mock_id, mock_response, data_path):
+ case = fl.Case(id="case-b3927b83-8af6-49cf-aa98-00d4f1838941")
+ params = case.params
+ x_force_dist = case.results.x_slicing_force_distribution
+ x_force_dist_by_boundary = x_force_dist.by_boundary_condition(params=params)
+
+ # Load reference CSVs
+ ref_x_force_dist_path = os.path.join(
+ "data", "case-b3927b83-8af6-49cf-aa98-00d4f1838941", "results", "x_force_dist_reference.csv"
+ )
+ ref_x_force_dist_by_boundary_path = os.path.join(
+ "data",
+ "case-b3927b83-8af6-49cf-aa98-00d4f1838941",
+ "results",
+ "x_force_dist_by_boundary_reference.csv",
+ )
+
+ ref_x_force_dist_df = pandas.read_csv(ref_x_force_dist_path)
+ ref_x_force_dist_by_boundary_df = pandas.read_csv(ref_x_force_dist_by_boundary_path)
+
+ ref_entity_group_by_boundary = {
+ "Wall-1": [
+ "body00001_face00001",
+ "body00001_face00002",
+ "body00001_face00003",
+ "body00001_face00004",
+ "body00001_face00005",
+ "body00001_face00006",
+ ],
+ "Freestream": ["farfield"],
+ "Wall-23": [
+ "body00002_face00001",
+ "body00002_face00002",
+ "body00002_face00003",
+ "body00002_face00004",
+ "body00002_face00005",
+ "body00002_face00006",
+ "body00003_face00001",
+ "body00003_face00002",
+ "body00003_face00003",
+ "body00003_face00004",
+ "body00003_face00005",
+ "body00003_face00006",
+ ],
+ }
+
+ assert x_force_dist_by_boundary._entity_groups == ref_entity_group_by_boundary
+
+ # Compare current results with reference
+ compare_dataframes_with_tolerance(x_force_dist.as_dataframe(), ref_x_force_dist_df)
+
+ compare_dataframes_with_tolerance(
+ x_force_dist_by_boundary.as_dataframe(),
+ ref_x_force_dist_by_boundary_df,
+ )
+
+ # Test y distribution
+ y_force_dist = case.results.y_slicing_force_distribution
+ y_force_dist_by_body = y_force_dist.by_body_group(params=params)
+
+ # Load reference CSVs for y distribution
+ ref_y_force_dist_path = os.path.join(
+ "data", "case-b3927b83-8af6-49cf-aa98-00d4f1838941", "results", "y_force_dist_reference.csv"
+ )
+ ref_y_force_dist_by_body_path = os.path.join(
+ "data",
+ "case-b3927b83-8af6-49cf-aa98-00d4f1838941",
+ "results",
+ "y_force_dist_by_body_reference.csv",
+ )
+
+ ref_y_force_dist_df = pandas.read_csv(ref_y_force_dist_path)
+ ref_y_force_dist_by_body_df = pandas.read_csv(ref_y_force_dist_by_body_path)
+
+ ref_entity_group_by_body = {
+ "body00001": [
+ "body00001_face00001",
+ "body00001_face00002",
+ "body00001_face00003",
+ "body00001_face00004",
+ "body00001_face00005",
+ "body00001_face00006",
+ ],
+ "body00002": [
+ "body00002_face00001",
+ "body00002_face00002",
+ "body00002_face00003",
+ "body00002_face00004",
+ "body00002_face00005",
+ "body00002_face00006",
+ ],
+ "body00003": [
+ "body00003_face00001",
+ "body00003_face00002",
+ "body00003_face00003",
+ "body00003_face00004",
+ "body00003_face00005",
+ "body00003_face00006",
+ ],
+ }
+
+ assert y_force_dist_by_body._entity_groups == ref_entity_group_by_body
+
+ # Compare current results with reference
+ compare_dataframes_with_tolerance(y_force_dist.as_dataframe(), ref_y_force_dist_df)
+
+ compare_dataframes_with_tolerance(
+ y_force_dist_by_body.as_dataframe(),
+ ref_y_force_dist_by_body_df,
+ )
diff --git a/tools/integrations/schema_generation_v2.py b/tools/integrations/schema_generation_v2.py
index f5f014219..10c8adf42 100644
--- a/tools/integrations/schema_generation_v2.py
+++ b/tools/integrations/schema_generation_v2.py
@@ -19,7 +19,7 @@
)
from flow360.component.simulation.meshing_param.volume_params import (
AutomatedFarfield,
- RotationCylinder,
+ RotationVolume,
UniformRefinement,
)
from flow360.component.simulation.models.material import SolidMaterial
@@ -147,7 +147,10 @@ def write_schemas(type_obj: Type[Flow360BaseModel], folder_name, file_suffix="")
file_suffix_part = f"-{file_suffix}" if file_suffix else ""
write_to_file(
os.path.join(
- here, data_folder, folder_name, f"json-schema-{version_postfix}{file_suffix_part}.json"
+ here,
+ data_folder,
+ folder_name,
+ f"json-schema-{version_postfix}{file_suffix_part}.json",
),
schema,
)
@@ -161,7 +164,6 @@ def write_example(
additional_fields: dict = {},
exclude=None,
):
-
if isinstance(obj, dict):
data = obj
elif isinstance(obj, Flow360BaseModel):
@@ -228,7 +230,7 @@ def write_example(
SurfaceEdgeRefinement(edges=[edge], method=AspectRatioBasedRefinement(value=2)),
],
volume_zones=[
- RotationCylinder(
+ RotationVolume(
entities=my_cylinder_1,
spacing_axial=0.1 * u.m,
spacing_radial=0.12 * u.m,
@@ -400,7 +402,9 @@ def write_example(
with SI_unit_system:
ac = AerospaceCondition.from_mach(
- mach=0.8, alpha=1 * u.deg, thermal_state=ThermalState(temperature=100 * u.K, density=2)
+ mach=0.8,
+ alpha=1 * u.deg,
+ thermal_state=ThermalState(temperature=100 * u.K, density=2),
)
write_example(
ac,