forked from amcastro-tri/SoftBubble
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalc_bubble_deformation_given_object_pose.m
78 lines (58 loc) · 2.06 KB
/
calc_bubble_deformation_given_object_pose.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
function [u, pr, dpdu, p_WP, normal0_W] = calc_bubble_deformation_given_object_pose(...
p_WP0, t, T0, ...
box_size, X_WB, ...
artificial_stiffness0)
% Compute normals at the nodes.
% Normals are the projection of the C0 face normals into the space of C1
% vector fields.
%[normal0_W, M, Fn] = calc_node_normals(p_WP0, t);
normal0_W = calc_area_weighted_normals(p_WP0, t);
% Assemble stiffness matrix and rhs.
nnodes = size(p_WP0, 1);
% Initial pressure for zero displacement.
u = zeros(nnodes, 1);
[pr, dpdu, H, phi0] = calc_nodal_pressure(p_WP0, normal0_W, box_size, X_WB, artificial_stiffness0);
K = sparse(nnodes, nnodes); % Zero matrix (i.e. an empty sparse matrix)
[K, F] = membrane3d_sparse(p_WP0, t, T0, u, pr, dpdu, K, true);
% Factorize matrix.
%Kfact = decomposition(K,'chol');
max_iters = 0;
rel_tol = 1.0e-3;
relaxation = 0.3;
p_WP = p_WP0;
% Solve for the normal deformation.
%u = gmres(K, F, [], rel_tol, 20, [], []); % u = K \ F;
u = K \ F;
% Update nodes positions.
% In this approximation we use the original normal (faster).
for inode = 1:nnodes
p_WP(inode, :) = p_WP0(inode, :) + u(inode) * normal0_W(inode, :);
end
u0 = u;
normal_W = normal0_W;
alpha = 1.0;
omega_alpha = 1.0;
for iter = 1:max_iters
% Update nodes positions.
% In this approximation we use the original normal (faster).
for inode = 1:nnodes
p_WP(inode, :) = p_WP0(inode, :) + u(inode) * normal_W(inode, :);
end
%normal_W = calc_area_weighted_normals(p_WP, t);
artificial_stiffness = alpha * artificial_stiffness0
alpha = omega_alpha * alpha;
% Update pressure. Keep the same normal.
[pr, dpdu] = calc_nodal_pressure(p_WP, normal_W, box_size, X_WB, artificial_stiffness);
% Update RHS using new positions p_WP.
[K, F] = membrane3d_sparse(p_WP, t, T0, u, pr, dpdu, K, false);
% Recompute deformations.
du = gmres(K, F, [], rel_tol, [], [], []);
u = relaxation * du + u0;
iter
residual = norm(du)/norm(u)
if (residual < rel_tol)
break;
end
u0 = u;
end
end