Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into dev-0.0.11
Browse files Browse the repository at this point in the history
  • Loading branch information
Krande committed Apr 30, 2021
2 parents 93a07d8 + 5c56e27 commit 30d6345
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 21 deletions.
15 changes: 2 additions & 13 deletions src/ada/core/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -870,14 +870,7 @@ def bbox(self):

@property
def vol_cog(self):
def get_middle(bbox, i):
return (bbox[i][0][i] + bbox[i][1][i]) / 2

return (
get_middle(self.bbox, 0),
get_middle(self.bbox, 1),
get_middle(self.bbox, 2),
)
return tuple([(self.bbox[i][0][i] + self.bbox[i][1][i]) / 2 for i in range(3)])

@property
def max_nid(self):
Expand All @@ -900,11 +893,7 @@ def get_by_volume(self, p=None, vol_box=None, vol_cyl=None, tol=1e-4):

p = np.array(p) if type(p) is (list, tuple) else p
if p is not None and vol_cyl is None and vol_box is None:
vol = [
(p[0] - tol, p[0] + tol),
(p[1] - tol, p[1] + tol),
(p[2] - tol, p[2] + tol),
]
vol = [(coord - tol, coord + tol) for coord in p]
elif vol_box is not None:
vol = list(zip(p, vol_box))
elif vol_cyl is not None and p is not None:
Expand Down
76 changes: 71 additions & 5 deletions src/ada/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
"create_guid",
"segments_to_local_points",
"zip_dir",
"replace_nodes_by_tol",
"replace_node",
]


Expand Down Expand Up @@ -373,9 +375,9 @@ def is_point_inside_bbox(p, bbox, tol=1e-3):
:return:
"""
if (
bbox[0][0] - tol < p[0] < bbox[0][1] + tol
and bbox[1][0] - tol < p[1] < bbox[1][1] + tol
and bbox[2][0] - tol < p[2] < bbox[2][1] + tol
bbox[0][0][0] - tol < p[0] < bbox[0][1][0] + tol
and bbox[1][0][1] - tol < p[1] < bbox[1][1][1] + tol
and bbox[2][0][2] - tol < p[2] < bbox[2][1][2] + tol
):
return True
else:
Expand Down Expand Up @@ -1764,9 +1766,9 @@ def convert_unit(size_in_bytes, unit):
if unit == SIZE_UNIT.KB:
return size_in_bytes / 1024
elif unit == SIZE_UNIT.MB:
return size_in_bytes / (1024 * 1024)
return size_in_bytes / (1024 ** 2)
elif unit == SIZE_UNIT.GB:
return size_in_bytes / (1024 * 1024 * 1024)
return size_in_bytes / (1024 ** 3)
else:
return size_in_bytes

Expand Down Expand Up @@ -2884,3 +2886,67 @@ def compute_minimal_distance_between_shapes(shp1, shp2):
logging.info("Minimal distance between shapes: ", dss.Value())

return dss


def replace_node(fem, old, new):
"""
:param fem: ada.fem
:param old:
:param new:
:type fem: ada.fem.FEM
:type old: ada.Node
:type new: ada.Node
"""

for elem in old.refs.copy():
# assert isinstance(ref, ada.fem.Elem)
try:
ref_index = elem.nodes.index(old)
except ValueError:
return
elem.nodes.pop(ref_index)

if new.id not in [e.id for e in elem.nodes]:
elem.nodes.insert(ref_index, new)

if len(elem.nodes) < 2:
fem.elements.remove_elements_by_id(elem.id)
old.refs.pop(old.refs.index(elem))
logging.error(f"Element removed due to coinciding nodes. Elem id {elem.id}")
elif len(elem.nodes) == (len(elem.edges_seq) - 1):
elem.change_type(len(elem.nodes))


def replace_nodes_by_tol(fem, decimals=0, tol=1e-4):
"""
:param fem:
:param decimals:
:param tol:
:type fem: ada.fem.FEM
"""

def rounding(vec, decimals_):
return np.around(vec, decimals=decimals_)

def n_is_most_precise(node, other_nodes_, decimals_=0):
most_precise = [np.array_equal(node.p, rounding(node.p, decimals_)) for node in [n] + other_nodes_]

if most_precise[0] and not np.all(most_precise[1:]):
return True
elif not most_precise[0] and np.any(most_precise[1:]):
return False
elif decimals_ == 10:
logging.error(f"Recursion started at 0 decimals, but are now at {decimals_} decimals. Will proceed with n.")
return True
else:
return n_is_most_precise(node, other_nodes_, decimals_ + 1)

for n in fem.nodes:
nearby_nodes = fem.nodes.get_by_volume(n.p, tol=tol)
other_nodes = list(filter(lambda x: x != n, nearby_nodes))
if len(other_nodes) > 0:
if n_is_most_precise(n, other_nodes, decimals):
for other_node in other_nodes:
replace_node(fem, other_node, n)
16 changes: 16 additions & 0 deletions src/ada/fem/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,22 @@ def remove_elements_by_set(self, elset):
p = elset.parent
p.sets.elements.pop(elset.name)

def remove_elements_by_id(self, ids):
"""
Remove elements from element ids. Will remove elements on completion
:param ids: Pass in a
:type ids: int or list of ints
"""
from collections.abc import Iterable

ids = list(ids) if isinstance(ids, Iterable) else [ids]
for id in ids:
if id in self._idmap.keys():
self._idmap.pop(id)
self._elements = list(self._idmap.values())
self._by_types = groupby(self._elements, key=attrgetter("type", "elset"))

def __contains__(self, item):
return item.id in self._idmap.keys()

Expand Down
28 changes: 25 additions & 3 deletions src/ada/fem/io/sesam/writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ def write(
d.write(self._mass_str)
d.write(self._bc_str)
d.write(self._hinges_str)
d.write(self._univec_str)
d.write(self._elem_str)
d.write(self._loads_str)
d.write("IEND 0.00 0.00 0.00 0.00")
Expand Down Expand Up @@ -302,11 +303,12 @@ def write_elem(el):
raise ValueError(f'Unsupported elem type "{fem_sec.type}"')

fixno = el.metadata.get("fixno", None)
transno = el.metadata.get("transno")
if fixno is None:
last_tuples = [(sec_id, 0, 0, 1)]
last_tuples = [(sec_id, 0, 0, transno)]
else:
h1_fix, h2_fix = fixno
last_tuples = [(sec_id, -1, 0, 1), (h1_fix, h2_fix)]
last_tuples = [(sec_id, -1, 0, transno), (h1_fix, h2_fix)]

return self.write_ff(
"GELREF1",
Expand Down Expand Up @@ -351,7 +353,7 @@ def _mass_str(self):

for mass in self._gmass.values():
for m in mass.fem_set.members:
if type(mass.mass) is float:
if type(mass.mass) in (int, float, np.float64):
masses = [mass.mass for _ in range(0, 3)] + [0, 0, 0]
else:
raise NotImplementedError()
Expand Down Expand Up @@ -397,6 +399,26 @@ def write_hinge(hinge):

return out_str

@property
def _univec_str(self):
from ada.core.utils import Counter

out_str = ""
unit_vector = Counter(0)

def write_local_z(vec):
transno = next(unit_vector)
data = [tuple([transno, *vec])]
return transno, self.write_ff("GUNIVEC", data)

for el in self._gelements:
local_z = el.fem_sec.local_z
transno, res_str = write_local_z(local_z)
out_str += res_str
el.metadata["transno"] = transno

return out_str

@property
def _loads_str(self):
out_str = ""
Expand Down

0 comments on commit 30d6345

Please sign in to comment.