Skip to content

Commit 654a939

Browse files
committed
reduce alloc in force addition
1 parent fb64b8a commit 654a939

File tree

1 file changed

+84
-68
lines changed

1 file changed

+84
-68
lines changed

src/Composition/dynamicCollision.jl

Lines changed: 84 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -34,32 +34,40 @@ end
3434
# further, at an event simulation status is updated, contact material is replaced
3535
# and the actual contactDict is stored
3636
function dealWithContacts!(sim, scene::Scene{F}, ch, world, time, file) where F <: Modia3D.VarFloatType
37-
simh = sim.eventHandler
38-
for (pairID, pair) in ch.contactDict
39-
obj1 = pair.obj1
40-
obj2 = pair.obj2
41-
rContact = (pair.contactPoint1 + pair.contactPoint2)/F(2.0)
42-
contactNormal = pair.contactNormal
37+
simh = sim.eventHandler
38+
f1::SVector{3,F}=Modia3D.ZeroVector3D(F)
39+
f2::SVector{3,F}=Modia3D.ZeroVector3D(F)
40+
t1::SVector{3,F}=Modia3D.ZeroVector3D(F)
41+
t2::SVector{3,F}=Modia3D.ZeroVector3D(F)
42+
43+
for (pairID, pair) in ch.contactDict
44+
obj1 = pair.obj1
45+
obj2 = pair.obj2
46+
rContact = (pair.contactPoint1 + pair.contactPoint2)/F(2.0)
47+
contactNormal = pair.contactNormal
48+
if ModiaLang.isEvent(sim)
49+
# println("$(sim.time): ", obj1.path, " ", obj2.path)
50+
getMaterialContactStart(scene, ch, simh, pair, pairID, obj1, obj2, rContact, contactNormal)
51+
visualizeContactAndSupportPoints(ch, world)
52+
end
53+
if scene.options.enableContactDetection
54+
(f1,f2,t1,t2) = responseCalculation(pair.contactPairMaterial, obj1, obj2,
55+
rContact, contactNormal,
56+
pair.distanceWithHysteresis, time, file, sim)
57+
58+
# Transform forces/torques in local part frames
59+
obj1.f += obj1.R_abs*f1
60+
obj1.t += obj1.R_abs*t1
61+
obj2.f += obj2.R_abs*f2
62+
obj2.t += obj2.R_abs*t2
63+
end
64+
end
65+
4366
if ModiaLang.isEvent(sim)
44-
# println("$(sim.time): ", obj1.path, " ", obj2.path)
45-
getMaterialContactStart(scene, ch, simh, pair, pairID, obj1, obj2, rContact, contactNormal)
46-
visualizeContactAndSupportPoints(ch, world)
67+
deleteMaterialLastContactDictContactEnd(scene, ch, simh)
4768
end
48-
if scene.options.enableContactDetection
49-
(f1,f2,t1,t2) = responseCalculation(pair.contactPairMaterial, obj1, obj2,
50-
rContact, contactNormal,
51-
pair.distanceWithHysteresis, time, file, sim)
52-
53-
# Transform forces/torques in local part frames
54-
obj1.f += obj1.R_abs*f1
55-
obj1.t += obj1.R_abs*t1
56-
obj2.f += obj2.R_abs*f2
57-
obj2.t += obj2.R_abs*t2
58-
end; end
59-
60-
if ModiaLang.isEvent(sim)
61-
deleteMaterialLastContactDictContactEnd(scene, ch, simh)
62-
end; end
69+
return nothing
70+
end
6371

6472

6573

@@ -68,62 +76,68 @@ end; end
6876
# if the actual shape pair was in contact at the last step as well, the already assigned contact material is taken
6977
# otherwise, contact material between these two shapes is choosen and simulation status is set
7078
function getMaterialContactStart(scene, ch, simh, pair, pairID, obj1, obj2, rContact, contactNormal)
71-
if haskey(ch.lastContactDict, pairID)
72-
# use material (reference) from previous event
73-
if scene.options.enableContactDetection
74-
pair.contactPairMaterial = ch.lastContactDict[pairID].contactPairMaterial # improve later (should avoid to inquire pairID twice)
75-
end
76-
else
77-
# determine contact pair material
78-
if scene.options.enableContactDetection
79-
pair.contactPairMaterial = contactStart(obj1, obj2, rContact, contactNormal,
80-
scene.options.elasticContactReductionFactor,
81-
scene.options.maximumContactDamping)
82-
end
83-
simh.restart = max(simh.restart, ModiaLang.Restart)
84-
simh.newEventIteration = false
85-
if scene.options.enableContactDetection
86-
logEvents(simh, pair, obj1, obj2, rContact, contactNormal)
87-
end
79+
if haskey(ch.lastContactDict, pairID)
80+
# use material (reference) from previous event
81+
if scene.options.enableContactDetection
82+
pair.contactPairMaterial = ch.lastContactDict[pairID].contactPairMaterial # improve later (should avoid to inquire pairID twice)
83+
end
84+
else
85+
# determine contact pair material
86+
if scene.options.enableContactDetection
87+
pair.contactPairMaterial = contactStart(obj1, obj2, rContact, contactNormal,
88+
scene.options.elasticContactReductionFactor,
89+
scene.options.maximumContactDamping)
90+
end
91+
simh.restart = max(simh.restart, ModiaLang.Restart)
92+
simh.newEventIteration = false
93+
if scene.options.enableContactDetection
94+
logEvents(simh, pair, obj1, obj2, rContact, contactNormal)
95+
end
96+
return nothing
8897
end; end
8998

9099
# important feature is stored at an event
91100
function logEvents(simh, pair, obj1, obj2, rContact, contactNormal)
92-
if simh.logEvents
93-
name1 = Modia3D.fullName(obj1)
94-
name2 = Modia3D.fullName(obj2)
95-
n = contactNormal
96-
println(" distance(", name1, ",", name2, ") = ", pair.distanceWithHysteresis, " became <= 0")
101+
if simh.logEvents
102+
name1 = Modia3D.fullName(obj1)
103+
name2 = Modia3D.fullName(obj2)
104+
n = contactNormal
105+
println(" distance(", name1, ",", name2, ") = ", pair.distanceWithHysteresis, " became <= 0")
97106

98-
@inbounds println(" contact normal = [", round(n[1], sigdigits=3), ", ", round(n[2], sigdigits=3), ", ", round(n[3], sigdigits=3), "], contact position = [", round(rContact[1], sigdigits=3), ", ", round(rContact[2], sigdigits=3), ", ", round(rContact[3], sigdigits=3),"], c_res = ", round(pair.contactPairMaterial.c_res, sigdigits=3) , " d_res = ", round(pair.contactPairMaterial.d_res, sigdigits=3))
99-
end; end
107+
@inbounds println(" contact normal = [", round(n[1], sigdigits=3), ", ", round(n[2], sigdigits=3), ", ", round(n[3], sigdigits=3), "], contact position = [", round(rContact[1], sigdigits=3), ", ", round(rContact[2], sigdigits=3), ", ", round(rContact[3], sigdigits=3),"], c_res = ", round(pair.contactPairMaterial.c_res, sigdigits=3) , " d_res = ", round(pair.contactPairMaterial.d_res, sigdigits=3))
108+
end
109+
return nothing
110+
end
100111

101112
# each contact shape pair which was in lastContactDict but isn't in actual contactDict
102113
# (= shape pair was in contact at last step but isn't at the actual step)
103114
# contact material is "deleted", it is set to nothing
104115
# and simulation status is set.
105116
# lastContactDict is deleted and filled with feature of the actual contactDict
106117
function deleteMaterialLastContactDictContactEnd(scene, ch, simh)
107-
for (pairID, pair) in ch.lastContactDict
108-
if !haskey(ch.contactDict, pairID)
109-
if scene.options.enableContactDetection
110-
contactEnd(pair.contactPairMaterial, pair.obj1, pair.obj2)
111-
end
112-
simh.restart = max(simh.restart, ModiaLang.Restart)
113-
simh.newEventIteration = false
114-
if !simh.logEvents # ModiaLang.isLogEvents(simh.logger)
115-
break
116-
end
117-
name1 = Modia3D.fullName(pair.obj1)
118-
name2 = Modia3D.fullName(pair.obj2)
119-
println(" distance(", name1, ",", name2, ") = ", pair.distanceWithHysteresis, " became > 0")
120-
end; end
121-
122-
# delete lastContactDict and save contactDict in lastContactDict
123-
empty!(ch.lastContactDict)
124-
for (pairID, pair) in ch.contactDict
125-
push!(ch.lastContactDict, pairID => pair)
126-
end; end
118+
for (pairID, pair) in ch.lastContactDict
119+
if !haskey(ch.contactDict, pairID)
120+
if scene.options.enableContactDetection
121+
contactEnd(pair.contactPairMaterial, pair.obj1, pair.obj2)
122+
end
123+
simh.restart = max(simh.restart, ModiaLang.Restart)
124+
simh.newEventIteration = false
125+
if !simh.logEvents # ModiaLang.isLogEvents(simh.logger)
126+
break
127+
end
128+
name1 = Modia3D.fullName(pair.obj1)
129+
name2 = Modia3D.fullName(pair.obj2)
130+
println(" distance(", name1, ",", name2, ") = ", pair.distanceWithHysteresis, " became > 0")
131+
end
132+
end
133+
134+
# delete lastContactDict and save contactDict in lastContactDict
135+
empty!(ch.lastContactDict)
136+
for (pairID, pair) in ch.contactDict
137+
push!(ch.lastContactDict, pairID => pair)
138+
end
139+
return nothing
140+
end
127141

128142

129143
### ------- visualizing contact and support points -----------------------------
@@ -188,6 +202,7 @@ function visualizeContactAndSupportPoints(ch, world::Composition.Object3D{F}) wh
188202
printWarnContSupPoints(nVisualContSupPoints)
189203
end
190204
end
205+
return nothing
191206
end
192207

193208
printWarnContSupPoints(nVisualContSupPoints) = @warn("If all contact points and/or support points should be visualized please set nVisualContSupPoints = $nVisualContSupPoints in Scene.")
@@ -196,4 +211,5 @@ printWarnContSupPoints(nVisualContSupPoints) = @warn("If all contact points and/
196211
function setVisualizationContactProperties!(obj::Composition.Object3D{F}, transparency::Float64, point::SVector{3,F}) where F <: Modia3D.VarFloatType
197212
obj.r_abs = point
198213
obj.feature.visualMaterial.transparency = transparency
214+
return nothing
199215
end

0 commit comments

Comments
 (0)