Skip to content

[Hotfix 25.5]: [FL-728] Add Default Report Config for Report Summary Table #1086

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions flow360/component/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
from flow360.component.volume_mesh import VolumeMeshV2
from flow360.exceptions import Flow360FileError, Flow360ValueError, Flow360WebError
from flow360.log import log
from flow360.plugins.report.report import get_default_report_summary_template
from flow360.version import __solver_version__

AssetOrResource = Union[type[AssetBase], type[Flow360Resource]]
Expand Down Expand Up @@ -1269,7 +1270,11 @@ def _run(
root asset (Geometry or VolumeMesh) is not initialized.
"""

<<<<<<< HEAD
use_geometry_AI = kwargs.get("use_geometry_AI", False) # pylint: disable=invalid-name
=======
# pylint: disable=too-many-branches
>>>>>>> a541a4bf ([FL-728] Add Default Report Config for Report Summary Table (#1074))
if use_beta_mesher is None:
if use_geometry_AI is True:
log.info("Beta mesher is enabled to use Geometry AI.")
Expand Down Expand Up @@ -1514,4 +1519,10 @@ def run_case(
raise_on_error=raise_on_error,
**kwargs,
)
report_template = get_default_report_summary_template()
report_template.create_in_cloud(
name="ResultSummary",
cases=[case],
solver_version=solver_version if solver_version else self.solver_version,
)
return case
2 changes: 1 addition & 1 deletion flow360/component/simulation/framework/updater_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def compare_lists(list1, list2, atol=1e-15, rtol=1e-10, ignore_keys=None):
if len(list1) != len(list2):
return False

if list1 and not isinstance(list1[0], dict):
if list1 and not any(isinstance(item, dict) for item in list1):
list1, list2 = sorted(list1), sorted(list2)

for item1, item2 in zip(list1, list2):
Expand Down
14 changes: 14 additions & 0 deletions flow360/component/simulation/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
ValidationContext,
)
from flow360.exceptions import Flow360RuntimeError, Flow360TranslationError
from flow360.plugins.report.report import get_default_report_summary_template
from flow360.version import __version__

unit_system_map = {
Expand Down Expand Up @@ -764,3 +765,16 @@ def update_simulation_json(*, params_as_dict: dict, target_python_api_version: s
# Expected exceptions
errors.append(str(e))
return updated_params_as_dict, errors


def get_default_report_config() -> dict:
"""
Get the default report config
Returns
-------
dict
default report config
"""
return get_default_report_summary_template().model_dump(
exclude_none=True,
)
40 changes: 39 additions & 1 deletion flow360/plugins/report/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
# pylint: disable=import-error
from pylatex import Section, Subsection

from flow360 import Case
from flow360.cloud.flow360_requests import NewReportRequest
from flow360.cloud.rest_api import RestApi
from flow360.component.case import Case
from flow360.component.interfaces import ReportInterface
from flow360.component.resource_base import AssetMetaBaseModel, Flow360Resource
from flow360.component.simulation.framework.base_model import Flow360BaseModel
Expand All @@ -32,6 +32,8 @@
Table,
)
from flow360.plugins.report.utils import (
Average,
DataItem,
RequirementItem,
get_requirements_from_data_path,
)
Expand Down Expand Up @@ -319,3 +321,39 @@ def create_pdf(
item.get_doc_item(case_context, self.settings)

report_doc.generate_pdf(os.path.join(data_storage, filename))


def get_default_report_summary_template() -> ReportTemplate:
"""
Returns default report template for result summary.
"""
avg = Average(fraction=0.1)

data = [
"volume_mesh/bounding_box/length",
"volume_mesh/bounding_box/height",
"volume_mesh/bounding_box/width",
"params/reference_geometry/moment_length",
"params/reference_geometry/area",
DataItem(data="surface_forces/totalCL", title="CL", operations=avg),
DataItem(data="surface_forces/totalCD", title="CD", operations=avg),
DataItem(data="surface_forces/totalCFy", title="CFy", operations=avg),
DataItem(data="surface_forces/totalCMx", title="CMx", operations=avg),
DataItem(data="surface_forces/totalCMy", title="CMy", operations=avg),
DataItem(data="surface_forces/totalCMz", title="CMz", operations=avg),
]
headers = [
"OAL",
"OAH",
"OAW",
"Reference Length",
"Reference Area",
"CL",
"CD",
"CFy",
"CMx",
"CMy",
"CMz",
]
table = Table(data=data, section_title="result_summary", headers=headers)
return ReportTemplate(items=[table], settings=Settings(dump_table_csv=True))
2 changes: 1 addition & 1 deletion flow360/plugins/report/report_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# pylint: disable=import-error
from pylatex import Document, Section, Subsection

from flow360 import Case
from flow360.component.case import Case


class ReportContext(pd.BaseModel):
Expand Down
16 changes: 16 additions & 0 deletions flow360/plugins/report/report_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,23 @@
# pylint: disable=import-error
from pylatex.utils import bold, escape_latex

<<<<<<< HEAD
from flow360 import Case, SimulationParams
from flow360.component.results import case_results
=======
from flow360.component.case import Case
>>>>>>> a541a4bf ([FL-728] Add Default Report Config for Report Summary Table (#1074))
from flow360.component.simulation.framework.base_model import Flow360BaseModel
from flow360.component.simulation.outputs.output_fields import (
IsoSurfaceFieldNames,
SurfaceFieldNames,
get_unit_for_field,
)
<<<<<<< HEAD
=======
from flow360.component.simulation.simulation_params import SimulationParams
from flow360.component.simulation.time_stepping.time_stepping import Unsteady
>>>>>>> a541a4bf ([FL-728] Add Default Report Config for Report Summary Table (#1074))
from flow360.component.simulation.unit_system import (
DimensionedTypes,
is_flow360_unit,
Expand Down Expand Up @@ -105,7 +114,10 @@ class Settings(Flow360BaseModel):
If not specified, defaults to 300.
"""

# pylint: disable=fixme
# TODO: Create a setting class for each type of report items.
dpi: Optional[pd.PositiveInt] = 300
dump_table_csv: Optional[pd.StrictBool] = False


class ReportItem(Flow360BaseModel):
Expand Down Expand Up @@ -405,6 +417,10 @@ def get_doc_item(self, context: ReportContext, settings: Settings = None) -> Non
table.add_row(formatted)
table.add_hline()

if settings is not None and settings.dump_table_csv:
df = self.to_dataframe(context=context)
df.to_csv(f"{self.section_title}.csv", index=False)


class PatternCaption(Flow360BaseModel):
"""
Expand Down
5 changes: 5 additions & 0 deletions flow360/plugins/report/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,13 @@
# pylint: disable=import-error
from pylatex import NoEscape, Package, Tabular

<<<<<<< HEAD
from flow360 import Case
from flow360.component.results import case_results
=======
from flow360.component.case import Case
from flow360.component.results import base_results, case_results
>>>>>>> a541a4bf ([FL-728] Add Default Report Config for Report Summary Table (#1074))
from flow360.component.simulation.framework.base_model import (
Conflicts,
Flow360BaseModel,
Expand Down
2 changes: 1 addition & 1 deletion flow360/plugins/report/uvf_shutter.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

import pydantic as pd

from flow360 import Env
from flow360.component.simulation.framework.base_model import Flow360BaseModel
from flow360.environment import Env
from flow360.exceptions import (
Flow360RuntimeError,
Flow360WebError,
Expand Down
17 changes: 17 additions & 0 deletions tests/data/mock_webapi/report_meta_resp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"data": {
"userId": "AIDAU77I6BZ2QYZLLVSRW",
"id": "rep-00508a80-2566-45bf-9572-56228a3161fd",
"status": "submitted",
"name": "ResultSummary",
"resources": [
{
"type": "Case",
"id": "case-f813742a-61d3-497c-8447-3ac8b0c997f1",
"rawData": null
}
],
"createdAt": "2025-05-19T18:30:51.476347Z",
"updatedAt": "2025-05-19T18:30:51.476347Z"
}
}
11 changes: 11 additions & 0 deletions tests/mock_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,16 @@ def json(self):
return res


class MockResponseReportSubmit(MockResponse):
"""response for report_template.create_in_cloud's meta json"""

@staticmethod
def json():
with open(os.path.join(here, "data/mock_webapi/report_meta_resp.json")) as fh:
res = json.load(fh)
return res


GET_RESPONSE_MAP = {
"/volumemeshes/00112233-4455-6677-8899-aabbccddeeff": MockResponseVolumeMesh,
"/volumemeshes/00000000-0000-0000-0000-000000000000": MockResponseVolumeMesh,
Expand Down Expand Up @@ -574,6 +584,7 @@ def json(self):
"/v2/drafts/vm-7c3681cd-8c6c-4db7-a62c-1742d825e9d3/run": MockResponseProjectVolumeMesh,
"/v2/drafts/case-84d4604e-f3cd-4c6b-8517-92a80a3346d3/simulation/file": MockResponseProjectCaseForkSimConfig,
"/v2/drafts/case-84d4604e-f3cd-4c6b-8517-92a80a3346d3/run": MockResponseProjectCaseFork,
"/v2/report": MockResponseReportSubmit,
}


Expand Down
112 changes: 112 additions & 0 deletions tests/simulation/service/ref/default_report_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
{
"items": [
{
"data": [
"volume_mesh/bounding_box/length",
"volume_mesh/bounding_box/height",
"volume_mesh/bounding_box/width",
"params/reference_geometry/moment_length",
"params/reference_geometry/area",
{
"data": "surface_forces/totalCL",
"title": "CL",
"operations": [
{
"fraction": 0.1,
"type_name": "Average"
}
],
"type_name": "DataItem"
},
{
"data": "surface_forces/totalCD",
"title": "CD",
"operations": [
{
"fraction": 0.1,
"type_name": "Average"
}
],
"type_name": "DataItem"
},
{
"data": "surface_forces/totalCFy",
"title": "CFy",
"operations": [
{
"fraction": 0.1,
"type_name": "Average"
}
],
"type_name": "DataItem"
},
{
"data": "surface_forces/totalCMx",
"title": "CMx",
"operations": [
{
"fraction": 0.1,
"type_name": "Average"
}
],
"type_name": "DataItem"
},
{
"data": "surface_forces/totalCMy",
"title": "CMy",
"operations": [
{
"fraction": 0.1,
"type_name": "Average"
}
],
"type_name": "DataItem"
},
{
"data": "surface_forces/totalCMz",
"title": "CMz",
"operations": [
{
"fraction": 0.1,
"type_name": "Average"
}
],
"type_name": "DataItem"
}
],
"section_title": "result_summary",
"headers": [
"OAL",
"OAH",
"OAW",
"Reference Length",
"Reference Area",
"CL",
"CD",
"CFy",
"CMx",
"CMy",
"CMz"
],
"type_name": "Table",
"formatter": [
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null
]
}
],
"include_case_by_case": false,
"settings": {
"dpi": 300,
"dump_table_csv": true
}
}
7 changes: 7 additions & 0 deletions tests/simulation/service/test_services_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -1258,3 +1258,10 @@ def _get_all_units(value):
f"Unit {unit_system_dimension_string} (A.K.A {field_name}) is not supported by the front-end.",
"Please ensure front end team is aware of this new unit and add its support.",
)


def test_get_default_report_config_json():
report_config_dict = services.get_default_report_config()
with open("ref/default_report_config.json", "r") as fp:
ref_dict = json.load(fp)
assert compare_values(report_config_dict, ref_dict, ignore_keys=["formatter"])