Skip to content

Commit 6ee373e

Browse files
committed
Cleanup
Change naming, refactor unpacking of numdata
1 parent 578afca commit 6ee373e

8 files changed

Lines changed: 40 additions & 49 deletions

File tree

scripts/test_fd_constraint_solver.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@
4040

4141
# set up iterative constraint solver
4242
numdata = FDNumericalData.from_params(vertices, fixed, edges, forcedensities, loads)
43-
solver = FDConstraintSolver(numdata, constraints, max_iter=30,
44-
tol_res=1E-3, tol_dxyz=1E-3)
43+
solver = FDConstraintSolver(numdata, constraints, kmax=30,
44+
tol_res=1E-3, tol_disp=1E-3)
4545

4646
# run solver
4747
result = solver()

scripts/test_fd_solver.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
# run solver
3232
result = solver()
33+
print(solver.iter_count)
3334

3435
# update mesh
3536
for index, vertex in enumerate(mesh.vertices()):

src/compas_fd/fd/fd_iter_numpy.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ def fd_iter_numpy(*,
2222
forcedensities: List[float],
2323
loads: Optional[Union[Sequence[Annotated[List[float], 3]], NDArray[(Any, 3), float64]]] = None,
2424
constraints: Sequence[Constraint],
25-
max_iter: int = 100,
25+
kmax: int = 100,
2626
tol_res: float = 1E-3,
27-
tol_dxyz: float = 1E-3
27+
tol_disp: float = 1E-3
2828
) -> Result:
2929
"""Iteratively compute the equilibrium coordinates of a system of vertices connected by edges.
3030
Vertex constraints are recomputed at each iteration.
3131
"""
3232
numdata = FDNumericalData.from_params(vertices, fixed, edges, forcedensities, loads)
33-
solver = FDConstraintSolver(numdata, constraints, max_iter, tol_res, tol_dxyz)
33+
solver = FDConstraintSolver(numdata, constraints, kmax, tol_res, tol_disp)
3434
result = solver()
3535
return result

src/compas_fd/fd/mesh_fd_iter_numpy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def mesh_fd_iter_numpy(mesh: 'compas_fd.datastructures.CableMesh') -> 'compas_fd
3333
constraints = list(mesh.vertices_attribute('constraint'))
3434

3535
numdata = FDNumericalData.from_params(vertices, fixed, edges, forcedensities, loads)
36-
solver = FDConstraintSolver(numdata, constraints, max_iter=100, tol_res=1E-3, tol_dxyz=1E-3)
36+
solver = FDConstraintSolver(numdata, constraints, kmax=100, tol_res=1E-3, tol_disp=1E-3)
3737
result = solver()
3838

3939
_update_mesh(mesh, result)

src/compas_fd/numdata/fd_numerical_data.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from nptyping import NDArray
99

1010
from dataclasses import dataclass
11-
from dataclasses import astuple
1211

1312
from numpy import asarray
1413
from numpy import float64
@@ -40,9 +39,6 @@ class FDNumericalData(NumericalData):
4039
tangent_residuals: NDArray[(Any, 3), float64] = None
4140
normal_residuals: NDArray[(Any, 1), float64] = None
4241

43-
def __iter__(self):
44-
return iter(astuple(self))
45-
4642
@classmethod
4743
def from_params(cls,
4844
vertices: Union[Sequence[Annotated[List[float], 3]], NDArray[(Any, 3), float64]],

src/compas_fd/solvers/fd_constraint_solver.py

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,45 +19,43 @@ class FDConstraintSolver(Solver):
1919
def __init__(self,
2020
numdata: FDNumericalData,
2121
constraints: Sequence[Constraint] = None,
22-
max_iter: int = 100,
23-
tol_dxyz: float = 1E-3,
22+
kmax: int = 100,
2423
tol_res: float = 1E-3,
24+
tol_disp: float = 1E-3,
2525
**kwargs
2626
) -> None:
27-
super(FDConstraintSolver, self).__init__(numdata, max_iter, **kwargs)
27+
super(FDConstraintSolver, self).__init__(numdata, kmax, **kwargs)
2828
self.constraints = constraints
29-
self.tol_dxyz = tol_dxyz
3029
self.tol_res = tol_res
30+
self.tol_disp = tol_disp
3131

3232
def solve(self) -> None:
3333
"""Apply force density algorithm for a single iteration."""
34-
free, fixed, xyz, C, q, Q, p, A, Ai, Af, *_ = self.numdata
35-
b = p[free] - Af.dot(xyz[fixed])
36-
xyz[free] = spsolve(Ai, b)
37-
self.numdata.residuals = p - A.dot(xyz)
38-
self.numdata.xyz_prev = xyz.copy()
39-
self.numdata.xyz = xyz
34+
nd = self.numdata
35+
b = nd.p[nd.free] - nd.Af.dot(nd.xyz[nd.fixed])
36+
nd.xyz[nd.free] = spsolve(nd.Ai, b)
37+
nd.residuals = nd.p - nd.A.dot(nd.xyz)
38+
nd.xyz_prev = nd.xyz.copy()
4039
self._update_constraints()
4140

4241
def _update_constraints(self):
4342
"""Update all vertex constraints by the residuals of the current iteration,
4443
and store their updated vertex coordinates in the numdata attribute.
4544
"""
46-
xyz = self.numdata.xyz
47-
residuals = self.numdata.residuals
45+
nd = self.numdata
4846
for vertex, constraint in enumerate(self.constraints):
4947
if not constraint:
5048
continue
51-
constraint.location = xyz[vertex]
52-
constraint.residual = residuals[vertex]
53-
xyz[vertex] = constraint.location + constraint.tangent * 0.5
54-
self.numdata.tangent_residuals = asarray([c.tangent for c in self.constraints if c])
55-
self.numdata.xyz = xyz
49+
constraint.location = nd.xyz[vertex]
50+
constraint.residual = nd.residuals[vertex]
51+
nd.xyz[vertex] = constraint.location + constraint.tangent * 0.5
52+
nd.tangent_residuals = asarray([c.tangent for c in self.constraints if c])
5653

5754
@property
5855
def is_converged(self) -> bool:
5956
"""Verify if all convergence criteria are met."""
60-
return self._is_converged_residuals and self._is_converged_xyz
57+
return (self._is_converged_residuals and
58+
self._is_converged_displacements)
6159

6260
@property
6361
def _is_converged_residuals(self) -> bool:
@@ -69,18 +67,16 @@ def _is_converged_residuals(self) -> bool:
6967
return max_res < self.tol_res
7068

7169
@property
72-
def _is_converged_xyz(self) -> bool:
70+
def _is_converged_displacements(self) -> bool:
7371
"""Verify whether the maximum coordinate displacement
7472
between consecutive iterations is within tolerance.
7573
"""
76-
new_xyz = self.numdata.xyz
77-
old_xyz = self.numdata.xyz_prev
78-
max_dxyz = max(norm(new_xyz - old_xyz, axis=1))
79-
return max_dxyz < self.tol_dxyz
74+
nd = self.numdata
75+
max_dxyz = max(norm(nd.xyz - nd.xyz_prev, axis=1))
76+
return max_dxyz < self.tol_disp
8077

8178
def post_process(self) -> None:
8279
"""Compute dependent variables after ending the solver loop."""
83-
_, _, xyz, C, q, *_ = self.numdata
84-
lengths = normrow(C.dot(xyz))
85-
self.numdata.forces = q * lengths
86-
self.numdata.lengths = lengths
80+
nd = self.numdata
81+
nd.lengths = normrow(nd.C.dot(nd.xyz))
82+
nd.forces = nd.q * nd.lengths

src/compas_fd/solvers/fd_solver.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ def __init__(self, numdata: FDNumericalData, **kwargs) -> None:
1616

1717
def solve(self) -> None:
1818
"""Apply force density algorithm for a single iteration."""
19-
free, fixed, xyz, C, q, Q, p, _, Ai, Af, *_ = self.numdata
20-
b = p[free] - Af.dot(xyz[fixed])
21-
xyz[free] = spsolve(Ai, b)
22-
self.numdata.xyz = xyz
19+
nd = self.numdata
20+
b = nd.p[nd.free] - nd.Af.dot(nd.xyz[nd.fixed])
21+
nd.xyz[nd.free] = spsolve(nd.Ai, b)
2322

2423
@property
2524
def is_converged(self) -> bool:
@@ -28,8 +27,7 @@ def is_converged(self) -> bool:
2827

2928
def post_process(self) -> None:
3029
"""Compute dependent variables after ending solver."""
31-
_, _, xyz, C, q, Q, p, A, *_ = self.numdata
32-
lengths = normrow(C.dot(xyz))
33-
self.numdata.lengths = lengths
34-
self.numdata.forces = q * lengths
35-
self.numdata.residuals = p - A.dot(xyz)
30+
nd = self.numdata
31+
nd.lengths = normrow(nd.C.dot(nd.xyz))
32+
nd.forces = nd.q * nd.lengths
33+
nd.residuals = nd.p - nd.A.dot(nd.xyz)

src/compas_fd/solvers/solver.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@ class Solver:
99

1010
def __init__(self,
1111
numdata: NumericalData,
12-
max_iter: int = 100,
12+
kmax: int = 100,
1313
**kwargs
1414
) -> None:
1515
self.numdata = numdata
16-
self.max_iter = max_iter
16+
self.kmax = kmax
1717
self.iter_count = 0
1818
self.result = None
1919

2020
def __call__(self) -> Result:
2121
"""Iteratively apply the solver algorithm."""
22-
for self.iter_count in range(1, self.max_iter + 1):
22+
for self.iter_count in range(1, self.kmax + 1):
2323
self.solve()
2424
if self.is_converged:
2525
break

0 commit comments

Comments
 (0)