Skip to content
Open
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
2 changes: 1 addition & 1 deletion .flake8
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[flake8]
max-line-length = 99

ignore = W503, F401, W605, E203
ignore = W503, F401, W605, E203, E231

exclude = test/*, doc/*, build/*, dist/* setup.py, installation/Pentagrow/*, INSTALLDIR/*
4 changes: 2 additions & 2 deletions installation/Pentagrow/frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ void FrontEnd::generateBoundaries(const std::string &fname, bool symmetry, Real
}
else
{
cout << "There are " << wall.nvertices() << " vertices." << endl;
//cout << "There are " << wall.nvertices() << " vertices." << endl;
uint tag, vertices[3];
std::map<int, int> tag_sym_vertex;
Vct3 symmetric_vertex;
Expand Down Expand Up @@ -446,7 +446,7 @@ int FrontEnd::generateMetric(int iter)

if (edgeGrowthFactor > 1.0)
{
if (edgeGrowthFactor < 1.1)
if (edgeGrowthFactor < 1.21)
cout << "[w] Tet growth factor very small." << endl;
else if (edgeGrowthFactor > 1.6)
cout << "[w] Tet growth factor very large." << endl;
Expand Down
26 changes: 26 additions & 0 deletions src/CEASIOMpyStreamlit/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import os
import sys
import shutil
import subprocess

from pathlib import Path
Expand Down Expand Up @@ -59,6 +60,31 @@ def main_exec():
src_path = str(PROJECT_ROOT / "src")
env["PYTHONPATH"] = src_path + os.pathsep + env.get("PYTHONPATH", "")

# If the ceasiompy conda env is not already active, try to run the script inside it.
target_conda_env = "ceasiompy"
active_conda = env.get("CONDA_DEFAULT_ENV")
if active_conda != target_conda_env:
# prefer conda, fall back to mamba
conda_bin = shutil.which("conda") or shutil.which("mamba")
if conda_bin:
# Use 'conda run' to execute inside the named env and let the env Python run the script
# (do NOT pass sys.executable here, otherwise conda run will execute the host python)
command = [
conda_bin,
"run",
"-n",
target_conda_env,
"--no-capture-output",
"python",
str(SCRIPT_ABSOLUTE_PATH),
] + script_args
else:
print(
f"Warning: conda/mamba not found; \
running with current interpreter (env={active_conda}).",
file=sys.stderr,
)

# --- Execute Script ---

try:
Expand Down
38 changes: 37 additions & 1 deletion src/CEASIOMpyStreamlit/guiobjects.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def float_vartype(tixi, xpath, default_value, name, key, description) -> None:
st.number_input(
name,
value=value,
format="%0.3f",
format="%g",
key=key,
help=description,
on_change=save_cpacs_file,
Expand All @@ -153,6 +153,42 @@ def list_vartype(tixi, xpath, default_value, name, key, description) -> None:
)


def add_ctrl_surf_vartype(tixi, xpath, default_value, name, key, description) -> None:
'''
Specific function for selecting a deformation angle in the CPACSUpdater module.
Special request of Giacomo Benedetti.
'''
if default_value is None:
log.warning(f"Could not create GUI for {xpath} in add_ctrl_surf_vartype.")
return None

ctrl_xpath = xpath + "/ctrlsurf"
angle_xpath = xpath + "/deformation_angle"

value = get_value_or_default(tixi, ctrl_xpath, default_value[0])
idx = default_value.index(value)
selected = st.radio(
name,
options=default_value,
index=idx,
key=key,
help=description,
on_change=save_cpacs_file,
)

# if value of st.radio is npot 'none' then add float_vartype entry
if selected is not None and str(selected).lower() != "none":
deformation_angle = get_value_or_default(tixi, angle_xpath, default_value=0.0)
float_vartype(
tixi,
angle_xpath,
deformation_angle, # Default value for deformation angle
"Deformation angle [deg]",
f"{key}_deformation_angle",
"Set the deformation angle for the selected control surface.",
)


def bool_vartype(tixi, xpath, default_value, name, key, description) -> None:
st.checkbox(
name,
Expand Down
8 changes: 8 additions & 0 deletions src/CEASIOMpyStreamlit/moduletab.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
aeromap_checkbox,
aeromap_selection,
multiselect_vartype,
add_ctrl_surf_vartype,
)

from typing import (
Expand Down Expand Up @@ -169,6 +170,12 @@ def add_gui_object(

session_state.xpath_to_update[xpath] = key

if var_type == "AddControlSurfaces":
session_state.xpath_to_update[xpath + "/ctrlsurf"] = key
session_state.xpath_to_update[
xpath + "/deformation_angle"
] = f"{key}_deformation_angle"


def add_module_tab(new_file: bool) -> None:
if "cpacs" not in st.session_state:
Expand All @@ -190,6 +197,7 @@ def add_module_tab(new_file: bool) -> None:
float: float_vartype,
list: list_vartype,
bool: bool_vartype,
"AddControlSurfaces": add_ctrl_surf_vartype,
}

dynamic_vartype_map = {
Expand Down
2 changes: 1 addition & 1 deletion src/bin/ceasiompy_exec.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def run_gui():
str(Path(__file__).resolve().parents[2] / "src") + os.pathsep + env.get("PYTHONPATH", "")
)
subprocess.run(
["streamlit", "run", "CEASIOMpy.py"],
["streamlit", "run", "CEASIOMpy.py", "--server.headless", "false"],
cwd=STREAMLIT_PATH,
check=True,
env=env,
Expand Down
1 change: 0 additions & 1 deletion src/ceasiompy/CPACS2GMSH/command.txt

This file was deleted.

1 change: 0 additions & 1 deletion src/ceasiompy/CPACS2GMSH/cpacs2gmsh.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
from cpacspy.cpacspy import CPACS

from ceasiompy import log

from ceasiompy.utils.commonxpaths import SU2MESH_XPATH
from ceasiompy.CPACS2GMSH import (
MODULE_NAME,
Expand Down
1 change: 1 addition & 0 deletions src/ceasiompy/CPACS2GMSH/func/generategmesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ def generate_gmsh(
- List of the aircraft parts in the model.

"""

# Determine if rotors are present in the aircraft model
rotor_model = cfg_rotors(brep_dir)

Expand Down
42 changes: 18 additions & 24 deletions src/ceasiompy/CPACS2GMSH/func/rans_mesh_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,21 @@
| Date: 2025-May-8

TODO:

- It may be good to move all the function and some of the code in generategmsh()
that are related to disk actuator to another python script and import it here

- Add mesh sizing for each aircraft part and as consequence add marker

- Integrate other parts during fragmentation

"""

# =================================================================================================
# IMPORTS
# =================================================================================================

import random
from itertools import combinations
import gmsh
import random

from ceasiompy.CPACS2GMSH.func.utils import (
check_path,
load_rans_cgf_params,
)
from ceasiompy.CPACS2GMSH.func.wingclassification import (
Expand All @@ -46,7 +42,6 @@
fuselage_size,
process_gmsh_log,
)
from ceasiompy import log
from ceasiompy.CPACS2GMSH.func.advancemeshing import (
refine_wing_section,
min_fields,
Expand All @@ -60,10 +55,13 @@
get_part_type,
run_software,
)
from ceasiompy.CPACS2GMSH.func.utils import check_path, MESH_COLORS

from pathlib import Path
from typing import Dict
from cpacspy.cpacspy import CPACS
from itertools import combinations

from ceasiompy import log
from ceasiompy.CPACS2GMSH.func.utils import MESH_COLORS


# =================================================================================================
Expand Down Expand Up @@ -522,9 +520,9 @@ def fusing_parts(aircraft_parts, symmetry, sym_box):
# in this case, either the pieces are not connected
# or the order was wrong and we took a non connected piece
counter += 1
log.info(
"Warning : the fusion did not give only one piece (will still try to see\
if it's a question of order)"
log.warning(
"The fusion did not give only one piece \
(will still try to see if it's a question of order)"
)
dimtags_names = (
[
Expand All @@ -536,7 +534,7 @@ def fusing_parts(aircraft_parts, symmetry, sym_box):
+ dimtags_names[j]["name"],
}
]
+ [{dimtags_names[k]} for k in range(len(dimtags_names)) if k != j and k != i]
+ [dimtags_names[k] for k in range(len(dimtags_names)) if k != j and k != i]
+ [
{
"dimtag": fused_entities[k],
Expand All @@ -550,10 +548,12 @@ def fusing_parts(aircraft_parts, symmetry, sym_box):
elif len(fused_entities) == 0:
counter += 1
namei, namej = dimtags_names[i]["name"], dimtags_names[j]["name"]
log.info(f"Warning : error, no fused entity (fused {namei} and {namej})")
log.warning(f"No fused entity (fused {namei} and {namej})")
# put them in the end to try again
dimtags_names = [
{dimtags_names[k]} for k in range(len(dimtags_names)) if k != j and k != i
dimtags_names[k]
for k in range(len(dimtags_names))
if k != j and k != i
] + [dimtags_names[i], dimtags_names[j]]
else:
# Update the vectors of remaining entities
Expand All @@ -566,13 +566,13 @@ def fusing_parts(aircraft_parts, symmetry, sym_box):

# Handle the cases where it didn't work
except Exception as e:
log.info(f"Fusion failed for entities {0} and {j}: {e}")
log.warning(f"Fusion failed for entities {0} and {j}: {e=}")
counter += 1
random.shuffle(dimtags_names)
if counter > 20:
# If here we have multiples times had problems with fusion and won't give one piece
names = [dimtags_names[k]["name"] for k in len(dimtags_names)]
log.info(f"Warning : the end result is not in one piece. Parts by group : {names}")
names = [dimtags_names[k]["name"] for k in range(len(dimtags_names))]
log.warning(f"The end result is not in one piece. Parts by group : {names}")
break

if symmetry:
Expand Down Expand Up @@ -976,12 +976,6 @@ def pentagrow_3d_mesh(

command = ["surface_mesh.stl", "config.cfg"]

# Specify the file path
file_path = "command.txt"

with open(file_path, "w") as file:
file.write(" ".join(command))

# Running command = "pentagrow surface_mesh.stl config.cfg"
run_software(
software_name="pentagrow",
Expand Down
2 changes: 1 addition & 1 deletion src/ceasiompy/CPACS2GMSH/func/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ def load_rans_cgf_params(
output_format: str,
) -> Dict:

InitialHeight = h_first_layer * (10**-5)
InitialHeight = h_first_layer * 1e-5
MaxLayerThickness = max_layer_thickness / 10
if fuselage_maxlen * farfield_factor > 10:
FarfieldRadius = 1000
Expand Down
2 changes: 1 addition & 1 deletion src/ceasiompy/CPACSUpdater/__specs__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
for wing_name, segment_name in segments_list:
cpacs_inout.add_input(
var_name=f"control_surface_{wing_name}_{segment_name}",
var_type=list,
var_type="AddControlSurfaces",
default_value=CONTROL_SURFACES_LIST,
unit=None,
descr="Type of control surface to add at specific wing and segment of wing.",
Expand Down
26 changes: 18 additions & 8 deletions src/ceasiompy/CPACSUpdater/func/controlsurfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
import numpy as np

from numpy import array
from cpacspy.cpacsfunctions import get_float_vector
from cpacspy.cpacsfunctions import (
get_float_vector,
get_value_or_default,
)
from ceasiompy.utils.mathsfunctions import (
rot,
rotate_2d_point,
Expand Down Expand Up @@ -91,9 +94,14 @@ def retrieve_gui_ctrlsurf(tixi: Tixi3) -> Dict[str, List]:
for j in range(1, seg_cnt + 1):
segment_name = tixi.getChildNodeName(wing_xpath, j)
segment_xpath = f"{wing_xpath}/{segment_name}"
segment_value = tixi.getTextElement(segment_xpath)
segment_value = tixi.getTextElement(segment_xpath + "/ctrlsurf")
deformation_angle = get_value_or_default(
tixi,
xpath=segment_xpath + "/deformation_angle",
default_value=0.0,
)
if segment_value != "none":
wing_sgt_list.append((segment_name, segment_value))
wing_sgt_list.append((segment_name, segment_value, deformation_angle))
result[wing_name] = wing_sgt_list

if not result:
Expand Down Expand Up @@ -664,18 +672,20 @@ def add_control_surfaces(tixi: Tixi3) -> None:
if ctrlsurf:
for wing_name, wing_data in ctrlsurf.items():
decompose_wing(tixi, wing_name)
for sgt, ctrltype in wing_data:
for (sgt, ctrltype, deformation_angle) in wing_data:
log.info(f'Updating {sgt=}, {ctrltype=}, with a {deformation_angle=}')

# Transform and scale original airfoil
transform_airfoil(tixi, sgt, ctrltype)

# Add small airfoil that will act as a control surface
add_airfoil(tixi, sgt, ctrltype)

# Test deflection function
# deflection_angle(tixi, ctrltype + "_" + sgt, angle=-20.0)
# deflection_angle(tixi, "right_" + ctrltype + "_" + sgt, angle=20.0)
# deflection_angle(tixi, "left_" + ctrltype + "_" + sgt, angle=-20.0)
# Deflection function
if deformation_angle != 0.0:
deflection_angle(tixi, ctrltype + "_" + sgt, angle=deformation_angle)
# deflection_angle(tixi, "right_" + ctrltype + "_" + sgt, angle=20.0)
# deflection_angle(tixi, "left_" + ctrltype + "_" + sgt, angle=-20.0)

log.info("Finished adding control surfaces.")
else:
Expand Down
Loading
Loading