-
Notifications
You must be signed in to change notification settings - Fork 2
Quick_Start_Examples #13
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
Open
thomascfd
wants to merge
8
commits into
master
Choose a base branch
from
thomas/Quick_Starts
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
3bbb23a
Quick_Start_Examples
thomascfd bcf0dca
Added XV15 Quick-Start + File paths
thomascfd c9e99d9
Added no limit in cases search
thomascfd b9e157d
Script Revisions according to Flow360Scripts Guidelines
thomascfd 4346e8f
Minor changes in code headers
thomascfd 2d2781b
Removed old Flow360 json file
thomascfd 1ed0bcd
Changed mesh ID for updated mesh with volumeZones
thomascfd ec2b9c6
Fixed some header titles
thomascfd File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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,13 @@ | ||
The following example demonstrates the use of automated meshing using the ONERA M6 wing. | ||
|
||
To run the demo case follow these steps: | ||
|
||
1. Run 'python3 submit_cases.py` -> this script will upload the geometry file to the Flexcompute servers, generate the surface and volume mesh and then submit the CFD case. | ||
|
||
2. Run `python download_data.py` -> this script will download the csv files containing the loads and residual histories. | ||
|
||
3. Run `python convergence_plots.py` -> this script will plot the load and residual convergence histories. | ||
|
||
4. Run `python download_plot_sectional_forces.py` -> this script will download and plot the sectional loads. | ||
|
||
5. Run `download_vis_figures.py` -> this script will download Cp, Cf and streamline visualizations to the folder vis_figures. |
82 changes: 82 additions & 0 deletions
82
examples/Quick_Starts/Automated_Meshing/convergence_plots.py
This file contains hidden or 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,82 @@ | ||
"""Plot the loads and residuals convergence plots for ONERA M6 automeshing quick-start""" | ||
|
||
import os | ||
|
||
import matplotlib.pyplot as plt | ||
import numpy as np | ||
import pandas as pd | ||
|
||
with open("case_name_list.dat", "r", encoding="utf-8") as file: | ||
case_name_list = file.read().splitlines() | ||
|
||
loads = ["CL", "CD"] | ||
residuals = ["0_cont", "1_momx", "2_momy", "3_momz", "4_energ", "5_nuHat"] | ||
figures = [] | ||
axes = [] | ||
|
||
|
||
def plot_loads(data, plot_name): | ||
"""Plot the loads""" | ||
x = data["pseudo_step"] | ||
for ax, load in zip(axes, loads): | ||
ax.plot(x, data[load], label=plot_name) | ||
ax.set_ylabel(load) | ||
ax.legend() | ||
ax.set_xlabel("Pseudo step") | ||
ax.grid(which="major", color="gray") | ||
if load == "CL": | ||
ax.set_ylim(0.27, 0.28) | ||
elif load == "CD": | ||
ax.set_ylim(0.017, 0.018) | ||
|
||
|
||
def plot_residuals(data, plot_name): | ||
"""Plot the residuals""" | ||
x = data["pseudo_step"] | ||
for ax, res in zip(axes, residuals): | ||
for res in residuals: | ||
ax.semilogy(x, data[res], label=plot_name + " " + res) | ||
ax.set_ylabel("Residuals") | ||
ax.legend(fontsize="8") | ||
ax.set_title("ONERAM6 - Automated Meshing Quick-Start") | ||
ax.grid(which="major", color="gray") | ||
ax.set_xlabel("Pseudo step") | ||
ax.set_yticks(10.0 ** np.arange(-14, -2)) | ||
ax.set_ylim([1e-7, 1e-2]) | ||
ax.set_xlim([0, 5000]) | ||
|
||
|
||
# set output directory | ||
dir_path = os.path.join(os.getcwd(), "figures") | ||
os.makedirs(dir_path, exist_ok=True) | ||
|
||
# initialize figures & axes | ||
for load in loads: | ||
fig, ax = plt.subplots(figsize=(8, 6)) | ||
figures.append(fig) | ||
axes.append(ax) | ||
|
||
# calculate and plot loads convergence histories | ||
for case_name in case_name_list: | ||
csv_path = os.path.join(os.getcwd(), f"{case_name}", "total_forces_v2.csv") | ||
data = pd.read_csv(csv_path, skipinitialspace=True) | ||
plot_loads(data, case_name) | ||
|
||
for i, load in enumerate(loads): | ||
figures[i].savefig(os.path.join(dir_path, load + ".png"), dpi=500) | ||
|
||
for ax in axes: | ||
ax.cla() | ||
|
||
|
||
# plot residual convergence histories | ||
fig, ax = plt.subplots(figsize=(8, 6)) | ||
figures.append(fig) | ||
axes.append(ax) | ||
|
||
for case_name in case_name_list: | ||
csv_path = os.path.join(os.getcwd(), case_name, "nonlinear_residual_v2.csv") | ||
data = pd.read_csv(csv_path, skipinitialspace=True) | ||
plot_residuals(data, case_name) | ||
|
||
figures[0].savefig(os.path.join(dir_path, "Residuals.png"), dpi=500) |
This file contains hidden or 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,29 @@ | ||
"""Download the results for the ONERA M6 automeshing quick-start""" | ||
|
||
import os | ||
|
||
from flow360 import MyCases | ||
|
||
# read in case_name_list | ||
with open("case_name_list.dat", "r", encoding="utf-8") as file: | ||
case_name_list = file.read().splitlines() | ||
|
||
my_cases = MyCases(limit=None) | ||
|
||
case = None | ||
|
||
for case_name in case_name_list: | ||
case_folder = os.path.join(os.getcwd(), case_name) | ||
os.makedirs(case_folder, exist_ok=True) | ||
# find the latest case with the name corresponding to the name in case_name_list | ||
for case in my_cases: | ||
if case.name == case_name: | ||
break | ||
print(case.name) | ||
# download the files | ||
case.results.download( | ||
nonlinear_residuals=True, | ||
surface_forces=True, | ||
total_forces=True, | ||
destination=case_folder, | ||
) |
58 changes: 58 additions & 0 deletions
58
examples/Quick_Starts/Automated_Meshing/download_plot_sectional_forces.py
This file contains hidden or 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,58 @@ | ||
"""Plot the sectional loads for the ONERA M6 wing automeshing quick-start case""" | ||
|
||
import os | ||
|
||
import matplotlib.pyplot as plt | ||
import pandas as pd | ||
from flow360 import MyCases | ||
|
||
with open("case_name_list.dat", "r", encoding="utf-8") as file: | ||
case_name_list = file.read().splitlines() | ||
|
||
loads = ["wing_CFx_per_span", "wing_CFz_per_span"] | ||
figures = [] | ||
axes = [] | ||
|
||
|
||
def plot_sectional_forces(data, plot_name): | ||
"""Plots the sectional loads""" | ||
for ax, load in zip(axes, loads): | ||
ax.plot(data["Y"], data["fluid/" + load], label=plot_name) | ||
ax.set_ylabel(load) | ||
ax.legend() | ||
ax.set_xlabel("Y") | ||
ax.grid(which="major", color="gray") | ||
|
||
|
||
case = None | ||
my_cases = MyCases(limit=None) | ||
|
||
for case_name in case_name_list: | ||
case_folder = os.path.join(os.getcwd(), case_name) | ||
os.makedirs(case_folder, exist_ok=True) | ||
# Find the latest case with the name corresponding to the name in caseNameList | ||
for case in my_cases: | ||
if case.name == case_name: | ||
break | ||
print(case.name) | ||
forces = "results/postprocess/forceDistribution.csv" | ||
# print(case.results) | ||
case._download_file(forces, to_folder=case_folder) | ||
|
||
# set output directory | ||
dir_path = os.path.join(os.getcwd(), "figures") | ||
os.makedirs(dir_path, exist_ok=True) | ||
|
||
# initialize figures & axes | ||
for load in loads: | ||
fig, ax = plt.subplots(figsize=(8, 6)) | ||
figures.append(fig) | ||
axes.append(ax) | ||
|
||
for case_name in case_name_list: | ||
csv_path = os.path.join(os.getcwd(), f"{case_name}", "forceDistribution.csv") | ||
data = pd.read_csv(csv_path, skipinitialspace=True) | ||
plot_sectional_forces(data, case_name) | ||
|
||
for i, load in enumerate(loads): | ||
figures[i].savefig(os.path.join(dir_path, load + ".png"), dpi=500) |
70 changes: 70 additions & 0 deletions
70
examples/Quick_Starts/Automated_Meshing/download_vis_figures.py
This file contains hidden or 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,70 @@ | ||
"""Downloads visualizations of surface CP, CF and streamlines""" | ||
|
||
import os | ||
|
||
from flow360 import MyCases | ||
from PIL import Image | ||
|
||
with open("case_name_list.dat", "r", encoding="utf-8") as file: | ||
case_name_list = file.read().splitlines() | ||
|
||
fields = ["Cp", "Cf", "Fv"] | ||
|
||
|
||
def fetch_png(case, field, res="H"): | ||
"""Download the required figures from Flexcompute servers""" | ||
# download the legend i.e. color bar | ||
case_name = case.name | ||
os.makedirs("visualize", exist_ok=True) | ||
|
||
legend = f"visualize/{field}Legend.png" | ||
case._download_file(legend, to_file=legend) | ||
|
||
# list all available theta and phi | ||
view_angles = [(0, 0), (180, 0)] | ||
for theta in [60, 120]: | ||
for phi in range(0, 360, 90): | ||
view_angles.append((theta, phi)) | ||
# download the contour + axis files | ||
for theta, phi in view_angles: | ||
fname = f"{theta:03d}_{phi:03d}.png" | ||
contour = f"visualize/{field}_{res}_{fname}" | ||
axis = f"visualize/Ax_{fname}" | ||
case._download_file(contour, to_file=contour) | ||
case._download_file(axis, to_file=axis) | ||
# load and overlap contour + axis + legend | ||
img_contour = Image.open(contour).convert("RGBA") | ||
img_axis = Image.open(axis) | ||
img_axis = img_axis.resize((img_axis.width * 3, img_axis.height * 3)) | ||
img_axis = img_axis.convert("RGBA") | ||
img_legend = Image.open(legend).convert("RGBA") | ||
background = Image.new("RGBA", img_contour.size, (67, 100, 200)) | ||
img_contour.paste(img_axis, (0, img_contour.height - img_axis.height), img_axis) | ||
img_contour.paste( | ||
img_legend, | ||
(-int(0.1 * img_contour.height), int(0.1 * img_contour.height)), | ||
img_legend, | ||
) | ||
background.paste(img_contour, (0, 0), img_contour) | ||
background.save( | ||
f"vis_figures/{case_name}_{field}_{res}_{theta:03d}_{phi:03d}_final.png" | ||
) | ||
|
||
|
||
# set output directory | ||
dir_path = os.path.join(os.getcwd(), "vis_figures") | ||
os.makedirs(dir_path, exist_ok=True) | ||
|
||
case = None | ||
my_cases = MyCases(limit=None) | ||
|
||
for case_name in case_name_list: | ||
case_folder = os.path.join(os.getcwd(), case_name) | ||
os.makedirs(case_folder, exist_ok=True) | ||
# Find the latest case with the name corresponding to the name in case_name_list | ||
for case in my_cases: | ||
if case.name == case_name: | ||
break | ||
print(case.name) | ||
for field in fields: | ||
fetch_png(case, field) |
This file contains hidden or 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,54 @@ | ||
{ | ||
"geometry" : { | ||
"refArea" : 1.15315084119231, | ||
"momentCenter" : [0.0, 0.0, 0.0], | ||
"momentLength" : [1.47602, 0.801672958512342, 1.47602] | ||
}, | ||
"volumeOutput" : { | ||
"outputFormat" : "tecplot", | ||
"animationFrequency" : -1, | ||
"outputFields": ["primitiveVars", "Mach"] | ||
}, | ||
"surfaceOutput" : { | ||
"outputFormat" : "tecplot", | ||
"animationFrequency" : -1, | ||
"outputFields": ["primitiveVars", "Cp", "Cf"] | ||
}, | ||
"navierStokesSolver" : { | ||
"absoluteTolerance" : 1e-10, | ||
"kappaMUSCL" : -1.0 | ||
}, | ||
"turbulenceModelSolver" : { | ||
"modelType" : "SpalartAllmaras", | ||
"absoluteTolerance" : 1e-8 | ||
}, | ||
"freestream" : | ||
{ | ||
"Reynolds" : 14.6e+6, | ||
"Mach" : 0.84, | ||
"Temperature" : 297.78, | ||
"alphaAngle" : 3.06, | ||
"betaAngle" : 0.0 | ||
}, | ||
"boundaries": { | ||
"fluid/symmetric": { | ||
"type": "SlipWall" | ||
}, | ||
"fluid/wing": { | ||
"type": "NoSlipWall" | ||
}, | ||
"fluid/farfield": { | ||
"type": "Freestream" | ||
} | ||
}, | ||
"timeStepping" : { | ||
"physicalSteps" : 1, | ||
"timeStepSize" : "inf", | ||
"maxPseudoSteps" : 5000, | ||
"CFL" : { | ||
"initial" : 1, | ||
"final": 200, | ||
"rampSteps" : 2250 | ||
} | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
examples/Quick_Starts/Automated_Meshing/om6SurfaceMesh.json
This file contains hidden or 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,28 @@ | ||
{ | ||
"maxEdgeLength": 0.15, | ||
"curvatureResolutionAngle": 10, | ||
"growthRate": 1.07, | ||
"edges": { | ||
"wingLeadingEdge": { | ||
"type": "aniso", | ||
"method": "height", | ||
"value": 3e-4 | ||
}, | ||
"wingTrailingEdge": { | ||
"type": "aniso", | ||
"method": "height", | ||
"value": 3e-4 | ||
}, | ||
"rootAirfoilEdge": { | ||
"type": "projectAnisoSpacing" | ||
}, | ||
"tipAirfoilEdge": { | ||
"type": "projectAnisoSpacing" | ||
} | ||
}, | ||
"faces": { | ||
"wing": { | ||
"maxEdgeLength": 0.15 | ||
} | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
examples/Quick_Starts/Automated_Meshing/om6VolumeMesh.json
This file contains hidden or 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,49 @@ | ||
{ | ||
"refinementFactor": 1.45, | ||
"refinement": [ | ||
{ | ||
"type": "cylinder", | ||
"radius": 1.1, | ||
"length": 2.0, | ||
"spacing": 0.075, | ||
"axis": [0,1,0], | ||
"center": [0.7,-1.0,0] | ||
}, | ||
{ | ||
"type": "cylinder", | ||
"radius": 2.2, | ||
"length": 2.0, | ||
"spacing": 0.1, | ||
"axis": [0,1,0], | ||
"center": [0.7,-1.0,0] | ||
}, | ||
{ | ||
"type": "cylinder", | ||
"radius": 3.3, | ||
"length": 2.0, | ||
"spacing": 0.175, | ||
"axis": [0,1,0], | ||
"center": [0.7,-1.0,0] | ||
}, | ||
{ | ||
"type": "cylinder", | ||
"radius": 4.5, | ||
"length": 2.0, | ||
"spacing": 0.225, | ||
"axis": [0,1,0], | ||
"center": [0.7,-1.0,0] | ||
}, | ||
{ | ||
"type": "cylinder", | ||
"radius": 6.5, | ||
"length": 14.5, | ||
"spacing": 0.3, | ||
"axis": [-1,0,0], | ||
"center": [2,-1.0,0] | ||
} | ||
], | ||
"volume": { | ||
"firstLayerThickness": 1.35e-06, | ||
"growthRate": 1.04 | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.