Skip to content

Commit

Permalink
fix: edge-connected plates has now conforming meshes
Browse files Browse the repository at this point in the history
  • Loading branch information
Krande committed Aug 3, 2023
1 parent fbb68b8 commit 3dcc7c7
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 9 deletions.
47 changes: 45 additions & 2 deletions src/ada/core/clash_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,9 @@ def find_beams_connected_to_plate(pl: Plate, beams: list[Beam]) -> list[Beam]:
from ada.api.containers import Nodes

nid = Counter(1)
nodes = Nodes([Node((bm.placement.get_absolute_placement().origin + (bm.n2.p + bm.n1.p) / 2), next(nid), refs=[bm]) for bm in beams])
nodes = Nodes(
[Node((bm.placement.get_absolute_placement().origin + (bm.n2.p + bm.n1.p) / 2), next(nid), refs=[bm]) for bm in
beams])

pmin = pl.bbox().p1
pmax = pl.bbox().p2
Expand Down Expand Up @@ -235,7 +237,48 @@ def reinforce_plate_pipe_pen(self, add_to_layer: str = None):
part.add_beam(Beam(next(reinforce_name), bm_p4, bm_p1, "HP140x8"), add_to_layer=add_to_layer)


def find_edge_connected_perpendicular_plates(plates: list[ada.Plate]) -> dict[ada.Plate, list[ada.Plate]]:
@dataclass
class PlateConnections:
mid_span_connected: dict[ada.Plate, list[ada.Plate]]
edge_connected: dict[ada.Plate, list[ada.Plate]]


def find_edge_connected_perpendicular_plates(plates: list[ada.Plate]) -> PlateConnections:
"""Find all plates that are connected to a plate edge and are perpendicular to that edge"""
plates = list(plates)
mid_span_connected = dict()
edge_connected = dict()

for pl1 in plates:
place1 = pl1.placement.get_absolute_placement()
eop = EquationOfPlane(pl1.poly.origin, pl1.poly.normal, pl1.poly.ydir)
p13d = place1.origin + pl1.poly.points3d
for pl2 in plates:
if pl1 == pl2:
continue
place2 = pl2.placement.get_absolute_placement()
p23d = place2.origin + pl2.poly.points3d
res = eop.return_points_in_plane(np.asarray(p23d))
if len(res) < 1:
continue

# pop out the elements in the numpy array res that are rows in p13d
res_clear = [r for r in res if not any(np.all(r == p) for p in p13d)]

if len(res) == 2 and len(res_clear) == 0:
if pl1 not in edge_connected:
edge_connected[pl1] = []
edge_connected[pl1].append(pl2)

if len(res_clear) == 2:
if pl1 not in mid_span_connected:
mid_span_connected[pl1] = []
mid_span_connected[pl1].append(pl2)

return PlateConnections(mid_span_connected, edge_connected)


def find_plates_that_share_only_1_edge(plates) -> dict[ada.Plate, list[ada.Plate]]:
"""Find all plates that are connected to a plate edge and are perpendicular to that edge"""
plates = list(plates)
edge_connected = dict()
Expand Down
8 changes: 5 additions & 3 deletions src/ada/fem/formats/calculix/write/writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,17 @@ def beam_str(fem_sec: FemSection):

def get_section_str(fem_sec: FemSection):
from .write_elements import must_be_converted_to_general_section
from ada.sections.categories import BaseTypes

sec_type = fem_sec.section.type
if "section_type" in fem_sec.metadata.keys():
return fem_sec.metadata["section_type"]

if must_be_converted_to_general_section(sec_type):
return CcxSecTypes.GENERAL
elif sec_type in Sc.box:
elif sec_type == BaseTypes.BOX:
return CcxSecTypes.BOX
elif sec_type in Sc.tubular:
elif sec_type == BaseTypes.TUBULAR:
return CcxSecTypes.PIPE
else:
raise Exception(f'Section "{sec_type}" is not yet supported by Calculix exporter.\n{traceback.format_exc()}')
Expand Down Expand Up @@ -168,7 +170,7 @@ def gen_set_str(fem_set: FemSet):
assert len(fem_set.metadata["gen_mem"]) == 3
el_root += "" if "," in el_root[-2] else ", "
set_str += (
el_root + "generate\n {}, {}, {}" "".format(*[no for no in fem_set.metadata["gen_mem"]]) + "\n"
el_root + "generate\n {}, {}, {}" "".format(*[no for no in fem_set.metadata["gen_mem"]]) + "\n"
)
else:
set_str += el_root + "\n " + " ".join([f"{no.id}," + next(newline) for no in members]).rstrip()[:-1] + "\n"
Expand Down
19 changes: 17 additions & 2 deletions src/ada/fem/meshing/concepts.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,10 +241,25 @@ def split_plates_by_plates(self):

plates = [obj for obj in self.model_map.keys() if type(obj) is Plate]

plate_map = find_edge_connected_perpendicular_plates(plates)
plate_con = find_edge_connected_perpendicular_plates(plates)

for pl1, con_plates in plate_map.items():
# fragment plates (ie. making all interfaces conformal) that are connected at their edges
for pl1, con_plates in plate_con.edge_connected.items():
pl1_gmsh_obj = self.model_map[pl1]
intersecting_plates = []
pl1_dim, pl1_ent = pl1_gmsh_obj.entities[0]

for pl2 in con_plates:
pl2_gmsh_obj = self.model_map[pl2]

for pl2_dim, pl2_ent in pl2_gmsh_obj.entities:
intersecting_plates.append((pl2_dim, pl2_ent))

self.model.occ.fragment(intersecting_plates, [(pl1_dim, pl1_ent)])
self.model.occ.synchronize()

# split plates that have plate connections at their mid-span
for pl1, con_plates in plate_con.mid_span_connected.items():
pl1_gmsh_obj = self.model_map[pl1]
intersecting_plates = []
pl1_dim, pl1_ent = pl1_gmsh_obj.entities[0]
Expand Down
4 changes: 2 additions & 2 deletions tests/core/clash/test_plate_checking.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ def test_plate_perpendicular_touching():
p = ada.Part("MyFem") / [pl1, pl1_5, pl2, pl3, pl4]
plates = p.get_all_physical_objects(by_type=ada.Plate)

plate_map = find_edge_connected_perpendicular_plates(plates)

plate_con = find_edge_connected_perpendicular_plates(plates)
plate_map = plate_con.mid_span_connected
assert len(plate_map.keys()) == 2 and pl3 in plate_map.keys() and pl4 in plate_map.keys()

pl3_res = plate_map[pl3]
Expand Down

0 comments on commit 3dcc7c7

Please sign in to comment.