Skip to content

Commit c15b3d5

Browse files
authored
Merge pull request #59 from fea2/main
Merge fork to main
2 parents 4bceb9f + 13002d0 commit c15b3d5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+9537
-4701
lines changed

.editorconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ indent_size = 4
2525

2626
[LICENSE]
2727
insert_final_newline = false
28+

docs/api/compas_fea2.model.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Parts
1818
.. autosummary::
1919
:toctree: generated/
2020

21-
DeformablePart
21+
Part
2222
RigidPart
2323

2424
Nodes

docs/api/compas_fea2.units.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
Units
33
********************************************************************************
44

5-
compas_fe2 can use Pint for units consistency.
5+
compas_fea2 can use Pint for units consistency.

docs/api/compas_fea2.utilities.rst

Lines changed: 0 additions & 25 deletions
This file was deleted.

docs/userguide/basics.model.rst

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,11 @@ Point(x=0.0, y=0.0, z=0.0)
3434
Besides coordinates, nodes have many other (optional) attributes.
3535

3636
>>> node.mass
37-
(None, None, None)
37+
[None, None, None, None, None, None]
3838
>>> node.temperature
3939
>>>
4040
>>> node.dof
4141
{'x': True, 'y': True, 'z': True, 'xx': True, 'yy': True, 'zz': True}
42-
>>> node.loads
43-
{}
44-
>>> node.displacements
45-
{}
46-
47-
Nodes also have a container for storing calculation results.
48-
49-
>>> node.results
50-
{}
5142

5243

5344
Elements

requirements.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@ compas_viewer
44
Click
55
matplotlib
66
pint
7-
python-dotenv
7+
python-dotenv
8+
h5py
9+
matplotlib

scripts/shape_transformation.py

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/compas_fea2/UI/viewer/__init__.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
from .viewer import FEA2Viewer
22
from .scene import FEA2ModelObject
33
from .scene import FEA2StepObject
4-
from .scene import FEA2StressFieldResultsObject
5-
from .scene import FEA2DisplacementFieldResultsObject
6-
from .scene import FEA2ReactionFieldResultsObject
4+
from .scene import FEA2Stress2DFieldResultsObject
5+
from .scene import FEA2NodeFieldResultsObject
76

87
from .primitives import (
98
_BCShape,
@@ -22,7 +21,6 @@
2221
"ArrowShape",
2322
"FEA2ModelObject",
2423
"FEA2StepObject",
25-
"FEA2StressFieldResultsObject",
26-
"FEA2DisplacementFieldResultsObject",
27-
"FEA2ReactionFieldResultsObject",
24+
"FEA2Stress2DFieldResultsObject",
25+
"FEA2NodeFieldResultsObject",
2826
]

src/compas_fea2/UI/viewer/drawer.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from compas.geometry import Line
44

55

6-
def draw_field_vectors(field_locations, field_vectors, scale_results, translate=0, high=None, low=None, cmap=None, **kwargs):
6+
def draw_field_vectors(locations, vectors, scale_results, translate=0, high=None, low=None, cmap=None, **kwargs):
77
"""Display a given vector field.
88
99
Parameters
@@ -17,25 +17,24 @@ def draw_field_vectors(field_locations, field_vectors, scale_results, translate=
1717
translate : float
1818
The translation factor for the results.
1919
"""
20-
vectors = []
2120
colors = []
22-
21+
lines = []
2322
if cmap:
24-
lengths = [v.length for v in field_vectors]
23+
lengths = [v.length for v in vectors]
2524
min_value = high or min(lengths)
2625
max_value = low or max(lengths)
2726
else:
28-
colors = [Color.red()] * len(field_vectors)
27+
colors = [Color.red()] * len(vectors)
2928

30-
for pt, vector in zip(list(field_locations), list(field_vectors)):
29+
for pt, vector in zip(list(locations), list(vectors)):
3130
if vector.length == 0:
3231
continue
3332
else:
3433
v = vector.scaled(scale_results)
35-
vectors.append(Line.from_point_and_vector(pt, v).translated(v * translate))
34+
lines.append(Line.from_point_and_vector(pt, v).translated(v * translate))
3635
if cmap:
3736
colors.append(cmap(vector.length, minval=min_value, maxval=max_value))
38-
return vectors, colors
37+
return lines, colors
3938

4039

4140
def draw_field_contour(model, field_locations, field_results, high=None, low=None, cmap=None, **kwargs):

src/compas_fea2/UI/viewer/scene.py

Lines changed: 36 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,14 @@
22
from __future__ import division
33
from __future__ import print_function
44

5-
from compas.scene import SceneObject # noqa: F401
65
from compas.colors import Color
76
from compas.colors import ColorMap
87
from compas.geometry import Vector
9-
10-
from .drawer import draw_field_contour
11-
from .drawer import draw_field_vectors
12-
8+
from compas.scene import SceneObject # noqa: F401
9+
from compas_viewer.scene import BufferGeometry # noqa: F401
1310
from compas_viewer.scene import Collection
14-
from compas_viewer.scene import GroupObject
11+
from compas_viewer.scene import GroupObject # noqa: F401
12+
1513
from compas_fea2.model.bcs import FixedBC
1614
from compas_fea2.model.bcs import PinnedBC
1715
from compas_fea2.model.bcs import RollerBCX
@@ -21,6 +19,9 @@
2119
from compas_fea2.UI.viewer.primitives import PinBCShape
2220
from compas_fea2.UI.viewer.primitives import RollerBCShape
2321

22+
from .drawer import draw_field_contour
23+
from .drawer import draw_field_vectors
24+
2425
color_palette = {
2526
"faces": Color.from_hex("#e8e5d4"),
2627
"edges": Color.from_hex("#4554ba"),
@@ -75,7 +76,7 @@ def __init__(self, fast=False, show_bcs=True, show_parts=True, show_connectors=T
7576
line_color = kwargs.get("line_color", color_palette["edges"])
7677
show_faces = kwargs.get("show_faces", True)
7778
show_lines = kwargs.get("show_lines", False)
78-
show_nodes = kwargs.get("show_nodes", False)
79+
show_nodes = kwargs.get("show_nodes", True)
7980
opacity = kwargs.get("opacity", 1.0)
8081
part_meshes = []
8182
if show_parts:
@@ -209,14 +210,14 @@ def __init__(self, scale_factor=1, **kwargs):
209210
step = kwargs.pop("item")
210211

211212
# DRAW PATTERNS
212-
patterns = []
213-
for pattern in step.patterns:
214-
pattern_forces = []
215-
for node, load in pattern.node_load:
213+
loadfields = []
214+
for load_field in step.load_fields:
215+
loadfield_forces = []
216+
for node, load in load_field.node_load:
216217
x = load.x or 0
217218
y = load.y or 0
218219
z = load.z or 0
219-
pattern_forces.append(
220+
loadfield_forces.append(
220221
(
221222
Vector(x * scale_factor, y * scale_factor, z * scale_factor), # .to_mesh(anchor=node.point)
222223
{
@@ -226,19 +227,19 @@ def __init__(self, scale_factor=1, **kwargs):
226227
},
227228
)
228229
)
229-
patterns.append(
230+
loadfields.append(
230231
(
231-
pattern_forces,
232+
loadfield_forces,
232233
{
233-
"name": f"PATTERN-{pattern.name}",
234+
"name": f"LOADFIELD-{load_field.name}",
234235
},
235236
)
236237
)
237238

238-
super().__init__(item=patterns, name=f"STEP-{step.name}", componets=None, **kwargs)
239+
super().__init__(item=loadfields, name=f"STEP-{step.name}", componets=None, **kwargs)
239240

240241

241-
class FEA2StressFieldResultsObject(GroupObject):
242+
class FEA2Stress2DFieldResultsObject(GroupObject):
242243
"""StressFieldResults object for visualization.
243244
244245
Parameters
@@ -254,83 +255,30 @@ class FEA2StressFieldResultsObject(GroupObject):
254255
255256
"""
256257

257-
def __init__(self, step, scale_factor=1, components=None, **kwargs):
258+
def __init__(self, model, components=None, show_vectors=1, plane="mid", show_contour=False, **kwargs):
258259
field = kwargs.pop("item")
259260

260-
field_locations = list(field.locations(step))
261+
field_locations = [e.reference_point for e in field.locations]
261262

262263
if not components:
263264
components = [0, 1, 2]
264265
names = {0: "min", 1: "mid", 2: "max"}
265266
colors = {0: Color.blue(), 1: Color.yellow(), 2: Color.red()}
266267

267268
collections = []
268-
for component in components:
269-
field_results = [v[component] for v in field.principal_components_vectors(step)]
270-
lines, _ = draw_field_vectors(field_locations, field_results, scale_factor, translate=-0.5)
271-
collections.append((Collection(lines), {"name": f"PS-{names[component]}", "linecolor": colors[component], "linewidth": 3}))
272-
273-
super().__init__(item=collections, name=f"RESULTS-{field.name}", **kwargs)
274-
275-
276-
class FEA2DisplacementFieldResultsObject(GroupObject):
277-
"""DisplacementFieldResults object for visualization.
278-
279-
Parameters
280-
----------
281-
field : :class:`compas_fea2.results.Field`
282-
The field to visualize.
283-
step : :class:`compas_fea2.problem.steps.Step`
284-
The step to visualize.
285-
scale_factor : float
286-
The scale factor for the visualization.
287-
components : list
288-
The components to visualize.
289-
290-
"""
291-
292-
# FIXME: component is not used
293-
def __init__(self, step, component=None, show_vectors=1, show_contour=False, **kwargs):
294-
295-
field = kwargs.pop("item")
296-
cmap = kwargs.get("cmap", ColorMap.from_palette("hawaii"))
297-
298-
group_elements = []
299269
if show_vectors:
300-
vectors, colors = draw_field_vectors([n.point for n in field.locations(step)], list(field.vectors(step)), show_vectors, translate=0, cmap=cmap)
301-
# group_elements.append((Collection(vectors), {"name": f"DISP-{component}", "linecolors": colors, "linewidth": 3}))
302-
for v, c in zip(vectors, colors):
303-
group_elements.append((v, {"name": f"DISP-{component}", "linecolor": c, "linewidth": 3}))
270+
for component in components:
271+
field_results = [v[component] for v in field.principal_components_vectors(plane)]
272+
lines, _ = draw_field_vectors(field_locations, field_results, show_vectors, translate=-0.5)
273+
collections.append((Collection(lines), {"name": f"PS-{names[component]}", "linecolor": colors[component], "linewidth": 3}))
304274

305275
if show_contour:
306-
from compas_fea2.model.elements import BeamElement
307-
308-
field_locations = list(field.locations(step))
309-
field_results = list(field.component(step, component))
310-
min_value = min(field_results)
311-
max_value = max(field_results)
312-
part_vertexcolor = draw_field_contour(step.model, field_locations, field_results, min_value, max_value, cmap)
313-
314-
# DRAW CONTOURS ON 2D and 3D ELEMENTS
315-
for part, vertexcolor in part_vertexcolor.items():
316-
group_elements.append((part._discretized_boundary_mesh, {"name": part.name, "vertexcolor": vertexcolor, "use_vertexcolors": True}))
276+
raise NotImplementedError("Contour visualization not implemented for stress fields.")
317277

318-
# DRAW CONTOURS ON 1D ELEMENTS
319-
for part in step.model.parts:
320-
for element in part.elements:
321-
vertexcolor = {}
322-
if isinstance(element, BeamElement):
323-
for c, n in enumerate(element.nodes):
324-
v = field_results[field_locations.index(n)]
325-
for p in range(len(element.section._shape.points)):
326-
vertexcolor[p + c * len(element.section._shape.points)] = cmap(v, minval=min_value, maxval=max_value)
327-
# vertexcolor = {c: Color.red() for c in range(2*len(element.section._shape.points))}
328-
group_elements.append((element.outermesh, {"name": element.name, "vertexcolor": vertexcolor, "use_vertexcolors": True}))
278+
super().__init__(item=collections, name=f"STRESS-{field.name}", **kwargs)
329279

330-
super().__init__(item=group_elements, name=f"RESULTS-{field.name}", **kwargs)
331280

332-
333-
class FEA2ReactionFieldResultsObject(GroupObject):
281+
class FEA2NodeFieldResultsObject(GroupObject):
334282
"""DisplacementFieldResults object for visualization.
335283
336284
Parameters
@@ -346,34 +294,33 @@ class FEA2ReactionFieldResultsObject(GroupObject):
346294
347295
"""
348296

349-
def __init__(self, step, component, show_vectors=1, show_contour=False, **kwargs):
350-
# FIXME: component is not used
351-
297+
def __init__(self, components=None, show_vectors=1, show_contour=False, **kwargs):
352298
field = kwargs.pop("item")
353299
cmap = kwargs.get("cmap", ColorMap.from_palette("hawaii"))
300+
components = components or ["x", "y", "z"]
354301

355302
group_elements = []
356303
if show_vectors:
357-
vectors, colors = draw_field_vectors([n.point for n in field.locations(step)], list(field.vectors(step)), show_vectors, translate=0, cmap=cmap)
358-
# group_elements.append((Collection(vectors), {"name": f"DISP-{component}", "linecolors": colors, "linewidth": 3}))
304+
vectors, colors = draw_field_vectors([n.point for n in field.locations], list(field.components_vectors(components)), show_vectors, translate=0, cmap=cmap)
305+
359306
for v, c in zip(vectors, colors):
360-
group_elements.append((v, {"name": f"DISP-{component}", "linecolor": c, "linewidth": 3}))
307+
group_elements.append((v, {"name": f"DISP-{''.join(components)}", "linecolor": c, "linewidth": 3}))
361308

362309
if show_contour:
363310
from compas_fea2.model.elements import BeamElement
364311

365-
field_locations = list(field.locations(step))
366-
field_results = list(field.component(step, component))
312+
field_locations = list(field.locations)
313+
field_results = [v.length for v in field.components_vectors(components)]
367314
min_value = min(field_results)
368315
max_value = max(field_results)
369-
part_vertexcolor = draw_field_contour(step.model, field_locations, field_results, min_value, max_value, cmap)
316+
part_vertexcolor = draw_field_contour(field.model, field_locations, field_results, min_value, max_value, cmap)
370317

371318
# DRAW CONTOURS ON 2D and 3D ELEMENTS
372319
for part, vertexcolor in part_vertexcolor.items():
373320
group_elements.append((part._discretized_boundary_mesh, {"name": part.name, "vertexcolor": vertexcolor, "use_vertexcolors": True}))
374321

375322
# DRAW CONTOURS ON 1D ELEMENTS
376-
for part in step.model.parts:
323+
for part in field.model.parts:
377324
for element in part.elements:
378325
vertexcolor = {}
379326
if isinstance(element, BeamElement):

0 commit comments

Comments
 (0)