-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add structured model result analysis (#31)
This PR adds structured mesh model results analysis using the `result.Result` class, which now automatically detects if the project folder contains flexible or structured mesh results files. A clone of the basic example for structured meshes is also added (`basic_structured.py`) to show a full structured mesh model analysis. The version number is bumped to 0.5.0 to publish all the structured mesh features added thus far. Other changes include: * The `relative_map_parts` argument to the `result.Result` class has been removed, as the path to the result netCDF files are now automatically resolved * Added the `result.faces._trim_to_faces_frame` function to convert structured mesh netCDF result files into the faces dataframe. * The `Result.edges` attribute is now optional, being populated only for flexible mesh models * Model-file locating algorithms are now shared between the `Runner` and `Result` classes using the `_paths` module * `result.base.TimeStepResolver` is now private, i.e. `_TimeStepResolver` * The `result.faces._extract` decorator is now type checked * Base classes are no longer included in the API documentation but inherited members are
- Loading branch information
Showing
27 changed files
with
1,393 additions
and
390 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
{% set version = "0.4.3" %} | ||
{% set version = "0.5.0" %} | ||
|
||
package: | ||
name: snl-delft3d-cec-verify | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
import os | ||
import tempfile | ||
from pathlib import Path | ||
from collections import defaultdict | ||
|
||
import pandas as pd | ||
import matplotlib.pyplot as plt | ||
|
||
from snl_d3d_cec_verify import CaseStudy, Report, Result, Runner, Template | ||
|
||
def get_d3d_bin_path(): | ||
|
||
env = dict(os.environ) | ||
|
||
if 'D3D_BIN' in env: | ||
root = Path(env['D3D_BIN'].replace('"', '')) | ||
print('D3D_BIN found') | ||
else: | ||
root = Path("..") / "src" / "bin" | ||
print('D3D_BIN not found') | ||
|
||
print(f'Setting bin folder path to {root.resolve()}') | ||
|
||
return root.resolve() | ||
|
||
template = Template("structured") | ||
runner = Runner(get_d3d_bin_path()) | ||
report = Report(79, "%d %B %Y") | ||
report_dir = Path("basic_structured_report") | ||
report_dir.mkdir(exist_ok=True) | ||
data = defaultdict(list) | ||
|
||
cases = CaseStudy(discharge=[4, 5, 6, 7, 8]) | ||
|
||
for i, case in enumerate(cases): | ||
|
||
with tempfile.TemporaryDirectory() as tmpdirname: | ||
|
||
# Create the project and then run it | ||
template(case, tmpdirname) | ||
runner(tmpdirname) | ||
|
||
# Pick up the results | ||
result = Result(tmpdirname) | ||
turb_ds = result.faces.extract_turbine_centre(-1, case) | ||
turb_u = turb_ds["$u$"].values.take(0) | ||
|
||
# Record data for table | ||
data["discharge"].append(case.discharge) | ||
data["u"].append(turb_u) | ||
|
||
# Add report section with plot | ||
report.content.add_heading( | ||
f"Discharge: {case.discharge} (cubic meters per second)", | ||
level=2) | ||
|
||
fig, ax = plt.subplots() | ||
turbz = result.faces.extract_turbine_z(-1, case) | ||
turbz["$u$"].plot(ax=ax, x="$x$", y="$y$") | ||
plot_name = f"discharge_case_{i}.png" | ||
plot_path = report_dir / plot_name | ||
plt.savefig(plot_path) | ||
|
||
report.content.add_image(plot_name, "u-velocity (m/s)") | ||
|
||
df = pd.DataFrame(data) | ||
report.content.add_heading("Results", level=2) | ||
report.content.add_table(df, | ||
index=False, | ||
caption="Turbine centre velocity per discharge level") | ||
|
||
report.title = "Basic Example (Structured Grid)" | ||
report.date = "today" | ||
|
||
with open(report_dir / "report.md", "wt") as f: | ||
for line in report: | ||
f.write(line) | ||
|
||
try: | ||
|
||
import pypandoc | ||
|
||
pypandoc.convert_file(f"{report_dir / 'report.md'}", | ||
'docx', | ||
outputfile=f"{report_dir / 'report.docx'}", | ||
extra_args=[f'--resource-path={report_dir}', | ||
'--reference-doc=reference.docx']) | ||
|
||
except ImportError: | ||
|
||
print(report) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
[metadata] | ||
name = SNL-Delft3D-CEC-Verify | ||
version = 0.4.3 | ||
version = 0.5.0 | ||
author = Mathew Topper | ||
author_email = [email protected] | ||
description = Automated verification of SNL-Delft3D-CEC based on the 2014 Mycek experiment | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from __future__ import annotations | ||
|
||
from abc import ABC, abstractmethod | ||
from typing import Optional, Type, TypeVar | ||
from pathlib import Path | ||
from dataclasses import dataclass | ||
|
||
from .types import StrOrPath | ||
|
||
|
||
@dataclass(frozen=True) | ||
class _BaseModelFinderDataclassMixin: | ||
project_path: StrOrPath | ||
|
||
|
||
class _BaseModelFinder(ABC, _BaseModelFinderDataclassMixin): | ||
|
||
@property | ||
@abstractmethod | ||
def path(self) -> Optional[Path]: | ||
pass # pragma: no cover | ||
|
||
def is_model(self) -> bool: | ||
if self.path is None: return False | ||
return True | ||
|
||
|
||
# Type variable with an upper bound of _BaseModelFinder | ||
U = TypeVar('U', bound=_BaseModelFinder) | ||
|
||
|
||
def get_model(project_path: StrOrPath, | ||
*model_classes: Type[U]) -> Optional[U]: | ||
|
||
model = None | ||
|
||
for ModelClass in model_classes: | ||
test_model = ModelClass(project_path) | ||
if test_model.is_model(): | ||
model = test_model | ||
break | ||
|
||
return model | ||
|
||
|
||
def find_path(project_path: StrOrPath, | ||
ext: str, | ||
partial: Optional[str] = None) -> Optional[Path]: | ||
|
||
if partial is None: | ||
file_root = "*" | ||
else: | ||
file_root = f"*{partial}*" | ||
|
||
files = list(Path(project_path).glob(f"**/{file_root}{ext}")) | ||
|
||
if len(files) > 1: | ||
msg = f"Multiple files detected with signature '{file_root}{ext}'" | ||
raise FileNotFoundError(msg) | ||
|
||
if not files: return None | ||
|
||
return files[0] |
Oops, something went wrong.