Skip to content

Commit 7ee6711

Browse files
committed
surfcae mesh progres, part fusion
1 parent 1b39034 commit 7ee6711

File tree

2 files changed

+138
-132
lines changed

2 files changed

+138
-132
lines changed

ceasiompy/CPACS2GMSH/cpacs2gmsh.py

+2
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ def cpacs2gmsh(cpacs_path, cpacs_out_path):
155155
results_dir,
156156
open_gmsh=open_gmsh,
157157
min_max_mesh_factor=min_max_mesh_factor,
158+
fuselage_mesh_size_factor=1,
159+
wing_mesh_size_factor=1.5,
158160
)
159161

160162
if gmesh_path.exists():

ceasiompy/CPACS2GMSH/func/RANS_mesh_generator.py

+136-132
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,12 @@
3535
from pathlib import Path
3636

3737
import gmsh
38-
from ceasiompy.CPACS2GMSH.func.generategmesh import (
39-
# duplicate_disk_actuator_surfaces,
40-
# control_disk_actuator_normal,
41-
# get_entities_from_volume,
38+
from ceasiompy.CPACS2GMSH.func.generategmesh import ( # duplicate_disk_actuator_surfaces,; control_disk_actuator_normal,; get_entities_from_volume,
4239
ModelPart,
4340
add_disk_actuator,
44-
fuselage_size,
4541
process_gmsh_log,
4642
)
43+
from ceasiompy.CPACS2GMSH.func.gmsh_utils import MESH_COLORS
4744
from ceasiompy.utils.ceasiomlogger import get_logger
4845

4946
# from ceasiompy.utils.commonnames import (
@@ -53,9 +50,12 @@
5350
# GMSH_ENGINE_CONFIG_NAME,
5451
# )
5552
from ceasiompy.utils.ceasiompyutils import get_part_type
56-
57-
# from ceasiompy.utils.commonxpath import GMSH_MESH_SIZE_WINGS_XPATH
53+
from ceasiompy.utils.commonxpath import GMSH_MESH_SIZE_FUSELAGE_XPATH, GMSH_MESH_SIZE_WINGS_XPATH
5854
from ceasiompy.utils.configfiles import ConfigFile
55+
from cpacspy.cpacsfunctions import create_branch
56+
57+
from ceasiompy.CPACS2GMSH.func.mesh_sizing import fuselage_size, wings_size
58+
5959

6060
log = get_logger()
6161

@@ -66,7 +66,15 @@
6666

6767

6868
def generate_2d_mesh_for_pentagrow(
69-
cpacs, cpacs_path, brep_dir, results_dir, open_gmsh, min_max_mesh_factor, symmetry=False
69+
cpacs,
70+
cpacs_path,
71+
brep_dir,
72+
results_dir,
73+
open_gmsh,
74+
min_max_mesh_factor,
75+
symmetry=False,
76+
fuselage_mesh_size_factor=1,
77+
wing_mesh_size_factor=1.5,
7078
):
7179
"""
7280
Function to generate a mesh from brep files forming an airplane
@@ -133,18 +141,22 @@ def generate_2d_mesh_for_pentagrow(
133141
gmsh.option.setNumber("General.Terminal", 0)
134142
# Log complexity
135143
gmsh.option.setNumber("General.Verbosity", 5)
144+
# Tollerance for boolean
145+
gmsh.option.setNumber("Geometry.ToleranceBoolean", 1e-5)
136146

137147
# Import each aircraft original parts / parent parts
138-
fuselage_volume_dimtags = []
139-
wings_volume_dimtags = []
140-
enginePylons_enginePylon_volume_dimtags = []
141-
engine_nacelle_fanCowl_volume_dimtags = []
142-
engine_nacelle_coreCowl_volume_dimtags = []
143-
vehicles_engines_engine_volume_dimtags = []
144-
vehicles_rotorcraft_model_rotors_rotor_volume_dimtags = []
145-
146-
fuselage_surface = []
147-
wing_surface = []
148+
# fuselage_volume_dimtags = []
149+
# wings_volume_dimtags = []
150+
# enginePylons_enginePylon_volume_dimtags = []
151+
# engine_nacelle_fanCowl_volume_dimtags = []
152+
# engine_nacelle_coreCowl_volume_dimtags = []
153+
# vehicles_engines_engine_volume_dimtags = []
154+
# vehicles_rotorcraft_model_rotors_rotor_volume_dimtags = []
155+
156+
# fuselage_surface = []
157+
# wing_surface = []
158+
aircraft_parts = []
159+
parts_parent_dimtag = []
148160

149161
log.info(f"Importing files from {brep_dir}")
150162

@@ -153,121 +165,22 @@ def generate_2d_mesh_for_pentagrow(
153165
part_entities = gmsh.model.occ.importShapes(str(brep_file), highestDimOnly=False)
154166
gmsh.model.occ.synchronize()
155167

156-
# Create the aircraft part object
157168
part_obj = ModelPart(uid=brep_file.stem)
158-
# maybe to cut off -->
159169
part_obj.part_type = get_part_type(cpacs.tixi, part_obj.uid)
160170

161-
if part_obj.part_type == "fuselage":
162-
fuselage_volume_dimtags.append(part_entities[0])
163-
model_bb = gmsh.model.get_bounding_box(
164-
fuselage_volume_dimtags[0][0], fuselage_volume_dimtags[0][1]
165-
)
166-
fuselage_surface_dimtags = gmsh.model.get_entities(2)
167-
print(f"fuselage_surface_dimtags{fuselage_surface_dimtags}")
168-
169-
elif part_obj.part_type == "wing":
170-
wings_volume_dimtags.append(part_entities[0])
171-
# return wings_volume_dimtags
172-
wing_surface_dimtags = gmsh.model.get_entities(2)
173-
wing_surface_dimtags = [
174-
tag for tag in wing_surface_dimtags if tag not in fuselage_surface_dimtags
175-
]
176-
177-
print(f"wing_surface_dimtags{wing_surface_dimtags}")
178-
179-
elif part_obj.part_type == "enginePylons/enginePylon":
180-
enginePylons_enginePylon_volume_dimtags.append(part_entities[0])
181-
# return enginePylons_enginePylon_volume_dimtags
182-
183-
elif part_obj.part_type == "engine/nacelle/fanCowl":
184-
engine_nacelle_fanCowl_volume_dimtags.append(part_entities[0])
185-
186-
elif part_obj.part_type == "engine/nacelle/coreCowl":
187-
engine_nacelle_coreCowl_volume_dimtags.append(part_entities[0])
188-
189-
elif part_obj.part_type == "vehicles/engines/engine":
190-
vehicles_engines_engine_volume_dimtags.append(part_entities[0])
171+
part_surfaces = [e for e in part_entities if e[0] == 2]
172+
part_obj.surfaces_tags = [tag for dim, tag in part_surfaces]
191173

192-
elif part_obj.part_type == "vehicles/rotorcraft/model/rotors/rotor":
193-
vehicles_rotorcraft_model_rotors_rotor_volume_dimtags.append(part_entities[0])
194-
else:
195-
log.warning(f"'{brep_file}' cannot be categorized!")
196-
return None
174+
# Add to the list of aircraft parts
175+
aircraft_parts.append(part_obj)
176+
parts_parent_dimtag.append(part_entities[0])
197177

198-
for fuselage_surface_dimtag in fuselage_surface_dimtags:
199-
fuselage_tags = fuselage_surface_dimtag[1]
200-
fuselage_surface.append(fuselage_tags)
201-
202-
for wing_surface_dimtag in wing_surface_dimtags:
203-
wing_tags = wing_surface_dimtag[1]
204-
wing_surface.append(wing_tags)
205-
206-
# gmsh.model.add_physical_group(2, surface, -1, name="aircraft_surface")
207-
208-
gmsh.model.add_physical_group(2, fuselage_surface, -1, name="fuselage_surface")
209-
gmsh.model.add_physical_group(2, wing_surface, -1, name="wing_surface")
210-
211-
gmsh.model.occ.synchronize()
212-
213-
log.info("Start manipulation to obtain a watertight volume")
214-
log.info("Cutting parts...")
215-
# we have to obtain a wathertight volume
216-
217-
# gmsh.model.occ.fragment(
218-
# wings_volume_dimtags,
219-
# fuselage_volume_dimtags,
220-
# )
221-
gmsh.model.occ.fuse(wings_volume_dimtags, wings_volume_dimtags, -1, False, False)
222-
log.info("Removing parts...")
223-
# gmsh.model.occ.cut(wings_volume_dimtags, fuselage_volume_dimtags, -1, False, False)
224-
225-
volume_inner_part = gmsh.model.occ.cut(
226-
wings_volume_dimtags, fuselage_volume_dimtags, -1, False, False
227-
)
228-
volume_inner_part = volume_inner_part[:-1]
229-
print(f"inner part={volume_inner_part}")
230-
volume_inner_part = [(3, 4), (3, 5)]
231-
232-
surface_inner_part = gmsh.model.occ.cut(
233-
wing_surface_dimtags, fuselage_surface_dimtags, -1, False, False
234-
)
235-
surface_inner_part = surface_inner_part[:-1]
236-
print(f"inner part={surface_inner_part}")
237-
surface_inner_part = [
238-
(2, 15),
239-
(2, 20),
240-
(2, 3),
241-
(2, 4),
242-
(2, 5),
243-
(2, 34),
244-
(2, 35),
245-
(2, 36),
246-
(2, 37),
247-
(2, 38),
248-
(2, 39),
249-
(2, 40),
250-
(2, 41),
251-
(2, 42),
252-
(2, 43),
253-
(2, 44),
254-
(2, 45),
255-
(2, 46),
256-
]
178+
log.info(f"Part : {part_obj.uid} imported")
257179

258180
gmsh.model.occ.synchronize()
259181

260-
gmsh.model.occ.remove(volume_inner_part)
261-
gmsh.model.occ.remove(surface_inner_part)
262-
gmsh.model.occ.synchronize()
263-
gmsh.fltk.run()
264-
log.info("Fusing parts...")
265-
# gmsh.model.occ.fuse(wings_volume_dimtags, fuselage_volume_dimtags, -1, False, False)
266-
gmsh.model.occ.fuse(wings_volume_dimtags, fuselage_volume_dimtags, -1, False, False)
267-
gmsh.model.occ.synchronize()
268-
269-
gmsh.fltk.run()
270-
182+
# Create external domain for the farfield
183+
model_bb = gmsh.model.getBoundingBox(-1, -1)
271184
model_dimensions = [
272185
abs(model_bb[0] - model_bb[3]),
273186
abs(model_bb[1] - model_bb[4]),
@@ -280,7 +193,66 @@ def generate_2d_mesh_for_pentagrow(
280193
model_bb[2] + model_dimensions[2] / 2,
281194
]
282195

283-
fuselage_maxlen, _ = fuselage_size(cpacs_path)
196+
log.info("Start manipulation to obtain a watertight volume")
197+
log.info("Fusing parts...")
198+
199+
# Ciclo di fusione
200+
while len(parts_parent_dimtag) > 1:
201+
fused_entities, mapping = gmsh.model.occ.fuse(
202+
[parts_parent_dimtag[0]], [parts_parent_dimtag[1]]
203+
)
204+
205+
gmsh.model.occ.synchronize()
206+
207+
# Aggiorna la lista delle entità fuse
208+
new_fused = fused_entities[0]
209+
parts_parent_dimtag = [new_fused] + parts_parent_dimtag[2:]
210+
211+
# Verifica le entità nel modello
212+
final_volume_numbers = gmsh.model.getEntities(3)
213+
214+
if len(final_volume_numbers) != 1 or final_volume_numbers[0][1] != 1:
215+
log.error(f"There are {len(final_volume_numbers)}, fusion not successful")
216+
log.error("You should have just one volume")
217+
218+
gmsh.model.occ.synchronize()
219+
220+
aircraft = ModelPart("aircraft")
221+
222+
for part in aircraft_parts:
223+
aircraft.points.extend(part.points)
224+
aircraft.lines.extend(part.lines)
225+
aircraft.surfaces.extend(part.surfaces)
226+
aircraft.volume.extend(part.volume)
227+
aircraft.points_tags.extend(part.points_tags)
228+
aircraft.lines_tags.extend(part.lines_tags)
229+
aircraft.surfaces_tags.extend(part.surfaces_tags)
230+
aircraft.volume_tag.extend(part.volume_tag)
231+
232+
print(part.surfaces_tags)
233+
234+
surfaces_group = gmsh.model.addPhysicalGroup(2, part.surfaces_tags)
235+
print(f"surfaces_group ={surfaces_group}")
236+
gmsh.model.setPhysicalName(2, surfaces_group, f"{part.uid}")
237+
part.physical_groups.append(surfaces_group)
238+
239+
# Set surface BC for each part of the aircraft
240+
# if part.part_type == "engine":
241+
# define_engine_bc(part, brep_dir)
242+
# else:
243+
# surfaces_group = gmsh.model.addPhysicalGroup(2, part.surfaces_tags)
244+
# if part.part_type == "rotor":
245+
# gmsh.model.setPhysicalName(
246+
# 2, surfaces_group, f"{part.uid}{ACTUATOR_DISK_INLET_SUFFIX}"
247+
# )
248+
# else:
249+
# gmsh.model.setPhysicalName(2, surfaces_group, f"{part.uid}")
250+
# part.physical_groups.append(surfaces_group)
251+
gmsh.model.occ.synchronize()
252+
253+
# gmsh.fltk.run()
254+
255+
fuselage_maxlen, fuselage_minlen = fuselage_size(cpacs_path)
284256

285257
# gmsh.model.occ.translate(
286258
# [(3, 1)],
@@ -290,17 +262,49 @@ def generate_2d_mesh_for_pentagrow(
290262
# )
291263

292264
gmsh.model.occ.synchronize()
293-
log.info("Manipulation finished")
265+
log.info("Geometry has been fused")
266+
267+
mesh_size_fuselage = ((fuselage_maxlen + fuselage_minlen) / 2) / fuselage_mesh_size_factor
268+
log.info(f"Mesh size fuselage={mesh_size_fuselage:.3f} m")
269+
270+
create_branch(cpacs.tixi, GMSH_MESH_SIZE_FUSELAGE_XPATH)
271+
cpacs.tixi.updateDoubleElement(GMSH_MESH_SIZE_FUSELAGE_XPATH, mesh_size_fuselage, "%.3f")
272+
273+
wing_maxlen, wing_minlen = wings_size(cpacs_path)
274+
mesh_size_wing = ((wing_maxlen * 0.8 + wing_minlen) / 2) / wing_mesh_size_factor
275+
log.info(f"Mesh size wing={mesh_size_wing:.3f} m")
276+
277+
create_branch(cpacs.tixi, GMSH_MESH_SIZE_WINGS_XPATH)
278+
cpacs.tixi.updateDoubleElement(GMSH_MESH_SIZE_WINGS_XPATH, mesh_size_wing, "%.3f")
279+
280+
for part in aircraft_parts:
281+
print(part.part_type)
282+
if part.part_type == "fuselage":
283+
part.mesh_size = mesh_size_fuselage
284+
gmsh.model.mesh.setSize(part.points, part.mesh_size)
285+
gmsh.model.setColor(part.surfaces, *MESH_COLORS[part.part_type], recursive=False)
286+
elif part.part_type in ["wing", "pylon"]:
287+
part.mesh_size = mesh_size_wing
288+
gmsh.model.mesh.setSize(part.points, part.mesh_size)
289+
gmsh.model.setColor(part.surfaces, *MESH_COLORS[part.part_type], recursive=False)
290+
# elif part.part_type == "engine":
291+
# part.mesh_size = mesh_size_engines
292+
# gmsh.model.mesh.setSize(part.points, part.mesh_size)
293+
# gmsh.model.setColor(part.surfaces, *MESH_COLORS[part.part_type], recursive=False)
294+
# elif part.part_type == "rotor":
295+
# part.mesh_size = mesh_size_propellers
296+
# gmsh.model.mesh.setSize(part.points, part.mesh_size)
297+
# gmsh.model.setColor(part.surfaces, *MESH_COLORS[part.part_type], recursive=False)
298+
299+
# mesh_size = model_dimensions[0] * float(min_max_mesh_factor) * (10**-3)
300+
# gmsh.option.set_number("Mesh.MeshSizeMin", mesh_size)
301+
# gmsh.option.set_number("Mesh.MeshSizeMax", mesh_size)
302+
# gmsh.option.setNumber("Mesh.StlOneSolidPerSurface", 2)
294303

295-
# Mesh generation
296304
log.info("Start of gmsh 2D surface meshing process")
297305

298306
gmsh.option.setNumber("Mesh.Algorithm", 6)
299307
gmsh.option.setNumber("Mesh.LcIntegrationPrecision", 1e-6)
300-
mesh_size = model_dimensions[0] * float(min_max_mesh_factor) * (10**-3)
301-
gmsh.option.set_number("Mesh.MeshSizeMin", mesh_size)
302-
gmsh.option.set_number("Mesh.MeshSizeMax", mesh_size)
303-
gmsh.option.setNumber("Mesh.StlOneSolidPerSurface", 2)
304308

305309
gmsh.model.occ.synchronize()
306310
gmsh.logger.start()

0 commit comments

Comments
 (0)