Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 25 additions & 7 deletions Modelica/Mechanics/Translational/Components/ElastoGap.mo
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ model ElastoGap "1D translational spring damper combination with gap"
parameter SI.TranslationalDampingConstant d(final min=0, start=1)
"Damping constant";
parameter SI.Position s_rel0=0 "Unstretched spring length";
parameter SI.Force f_ref(min=0) = c*s_ref "Reference spring force at s_ref" annotation(Dialog(tab="Advanced"));
parameter SI.Length s_ref(min=Modelica.Constants.eps) = 1 "Reference relative compression at which f_c = f_ref" annotation(Dialog(tab="Advanced"));
parameter Real n(final min=1) = 1
"Exponent of spring force ( f_c = -c*|s_rel-s_rel0|^n )";
"Exponent of spring force ( f_c = -f_ref*|(s_rel-s_rel0)/s_ref|^n )";
extends Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT;

/*
Expand All @@ -22,14 +24,15 @@ protected
SI.Force f_d2 "Linear damping force";
SI.Force f_d
"Linear damping force which is limited by spring force (|f_d| <= |f_c|)";
Real ratio "Scaling ratio of relative compression to s_ref";
equation
// Modify contact force, so that it is only "pushing" and not
// "pulling/sticking" and that it is continuous
contact = s_rel < s_rel0;
f_c = smooth(1, noEvent(if contact then -c*abs(s_rel - s_rel0)^n else 0));
ratio = (s_rel - s_rel0)/s_ref;
f_c = smooth(1, noEvent(if contact then -f_ref*abs(ratio)^n else 0));
f_d2 = if contact then d*v_rel else 0;
f_d = smooth(0, noEvent(if contact then (if f_d2 < f_c then f_c else if
f_d2 > -f_c then -f_c else f_d2) else 0));
f_d = smooth(0, noEvent(if contact then min(max(f_d2, f_c), -f_c) else 0));
f = f_c + f_d;
lossPower = f_d*v_rel;
annotation (
Expand All @@ -49,7 +52,7 @@ a nonlinear spring force can be modeled:
</p>

<blockquote><pre>
desiredContactForce = c*|s_rel - s_rel0|^n + d*<strong>der</strong>(s_rel)
desiredContactForce = f_ref*|(s_rel - s_rel0)/s_ref|^n + d*<strong>der</strong>(s_rel)
</pre></blockquote>

<p>
Expand Down Expand Up @@ -112,8 +115,23 @@ If s_rel0 = 0, the equations are:
</pre></blockquote>

<p>
Note, since |f_d| &le; |f_c|, pulling forces cannot occur and the contact force
is always continuous, especially around the start of the penetration at s_rel = s_rel0.
Note, since |f_d|&nbsp;&le;&nbsp;|f_c|, pulling forces cannot occur and the contact force
is always continuous, especially around the start of the penetration at s_rel&nbsp;= s_rel0.
On the contrary, this leads to the contact force <code>f&nbsp;=&nbsp;0</code> even if
<code>contact&nbsp;= true</code> is still indicated around the end of the penetration.
This is because <code>contact</code> indicates only the occurance of geometry penetration.
</p>

<p>
In order to have consistent units for nonlinear springs, the term <code>c*|s_rel|^n</code>
is replaced by <code>f_ref*|s_rel/s_ref|^n</code>, whereby <code>s_ref</code> is a&nbsp;reference
length for the spring and <code>f_ref</code> is the spring force when
<code>s_rel&nbsp;=&nbsp;s_ref</code>. The default values <code>s_ref&nbsp;=&nbsp;1</code>
and <code>f_ref&nbsp;= c*s_ref</code> lead to the same results of the two above-mentioned terms.
Setting the advanced parameters <code>s_ref</code> and <code>f_ref</code> for a&nbsp;nonlinear
spring directly gives a&nbsp;cleaner and straightforward parametrization.
For simplicity reasons, both <code>s_ref</code> and <code>f_ref</code> are considered being
positive.
</p>

<p>
Expand Down