1

I'm trying to simulate Coulomb friction in Modelica. The basic concept is to check if relative velocity speed between to surfaces is less than a constant and the external force which tried to slid surfaces against each other is less than maximum static friction force (normalForce * staticFrictionCoefficient) then the friction force is equal to negative of the external shear force. otherwise, the friction force is equal to the kinetic friction force (normalForce * kineticFrictionCoefficient)in the opposite direction of the sliding direction. I implemented this concept in Modelica as below:

function coulombFriction

  input Real relVel;
  input Real shearForce;
  input Real normalForce;
  input Real statfricco;
  input Real kinfricco;
  output Real fricForce;

algorithm
  if relVel==0 and abs(shearForce)<statfricco*normalForce then
    fricForce:=shearForce;
  else
    fricForce:=kinfricco*normalForce*sign(relVel);
  end if;
end coulombFriction;

but when I call this function from a model as below:

model fricexample_1

  extends coulombFriction;

  //parameters
  parameter Real kco=0.3;
  parameter Real sco=0.4;
  parameter Real nfo=1.0;

  Real sfo;
  Real ffo;
  Real x;
  Real v;

  initial equation
  x=0;
  v=0;

  equation
  v=der(x);
  der(v)=sfo-ffo;
  sfo=time;
  ffo=coulombFriction(relVel=v, shearForce=sfo, normalForce=nfo, statfricco=sco, kinfricco=kco);

  end fricexample_1;

I see the error:

Translation Error

post-optimization module findZeroCrossings (simulation) failed.

If I remove the abs function from the defined function, it solves the compiling problem, but the model is wrong! I would appreciate if you could help me know:

  1. how can I solve this problem?
  2. how to model friction otherwise?
Community
  • 1
  • 1
Foad S. Farimani
  • 12,396
  • 15
  • 78
  • 193

4 Answers4

3

You can use noEvent on the conditions that might generate events in the function. Note that you don't need to extend the model with the function. It should actually not work (to extend a model from a function), but it seems we don't check for it.

The model that compiles for me is below:

package Friction

  function coulombFriction
    input Real relVel;
    input Real shearForce;
    input Real normalForce;
    input Real statfricco;
    input Real kinfricco;
    output Real fricForce;
  algorithm
    if noEvent(relVel==0) and noEvent(abs(shearForce)<statfricco*normalForce) then
      fricForce:=shearForce;
    else
      fricForce:=kinfricco*normalForce*sign(relVel);
    end if;
  end coulombFriction;

  model fricexample_1

    //parameters
    parameter Real kco=0.3;
    parameter Real sco=0.4;
    parameter Real nfo=1.0;

    Real sfo;
    Real ffo;
    Real x;
    Real v;

  initial equation
    x = 0;
    v = 0;

  equation
    v = der(x);
    der(v) = sfo-ffo;
    sfo = time;
    ffo = coulombFriction(relVel=v, shearForce=sfo, normalForce=nfo, statfricco=sco, kinfricco=kco);
  end fricexample_1;

end Friction;
Adrian Pop
  • 4,034
  • 13
  • 16
3

Your model does work with the 1.11 release. The issue is the extends coulombFriction; statement. Once you removed it, it should work fine even without the noEvent calls:

package Friction
  function coulombFriction
    input Real relVel;
    input Real shearForce;
    input Real normalForce;
    input Real statfricco;
    input Real kinfricco;
    output Real fricForce;
  algorithm
    if relVel==0 and abs(shearForce)<statfricco*normalForce then
      fricForce:=shearForce;
    else
      fricForce:=kinfricco*normalForce*sign(relVel);
    end if;
  end coulombFriction;

  model fricexample_1
    parameter Real kco=0.3;
    parameter Real sco=0.4;
    parameter Real nfo=1.0;

    Real sfo;
    Real ffo;
    Real x;
    Real v;

  initial equation
    x = 0;
    v = 0;

  equation
    v = der(x);
    der(v) = sfo-ffo;
    sfo = time;
    ffo = coulombFriction(relVel=v, shearForce=sfo, normalForce=nfo, statfricco=sco, kinfricco=kco);
  end fricexample_1;
end Friction;
lochel
  • 94
  • 4
  • you are actually true. extends is the main issue. but the question is if not extend then how can I include a .mo file in another model. I want to make some functions which I can reuse in other models. – Foad S. Farimani Feb 08 '17 at 13:34
  • 1
    Therefore, you could probably use the package system in Modelica: http://book.xogeny.com/components/packages/ – lochel Feb 08 '17 at 17:43
2

I'd recommend to reuse the friction state machine available in the Modelica Standard Library. An example, that works in OpenModelica and other tools, is given by https://github.com/dzimmer/ZimmersModelicaTutorial/blob/master/Tutorial2015/BaseComponents/Friction/IdealDryFriction.mo.

DelmeDelmi
  • 320
  • 1
  • 5
0

Actually, the model I have developed above for Columb friction is wrong. Thanks to this post I could find the correct version:

package friction1D

  final constant Real eps=1.e-15 "Biggest number such that 1.0 + eps = 1.0";

  function sgn
    input Real inputVar;
    output Real outputVar;
  algorithm
    if noEvent(inputVar < 0) then
     outputVar := -1;
    else
      outputVar := 1;
    end if;
  end sgn;

  function coulombFriction
    input Real relVel;
    input Real shearForce;
    input Real normalForce;
    input Real statfricco;
    input Real kinfricco;
    output Real fricForce;
  algorithm
      if noEvent(abs(relVel) < eps) and noEvent(abs(shearForce) < statfricco * normalForce) then
        fricForce := shearForce;
    else
      fricForce := kinfricco * normalForce * sgn(relVel);
    end if;
  end coulombFriction;

  model fricexample_1
    //parameters
    parameter Real kco = 0.3;
    parameter Real sco = 0.4;
    parameter Real nfo = 1.0;
    parameter Real mass = 1.0;

    Real sfo;
    Real ffo;
    Real x;
    Real v;

  initial equation
    x = 0;
    v = 0;

  algorithm
    sfo := 0.7 * sin(time);
    ffo := coulombFriction(relVel = v, shearForce = sfo, normalForce = nfo, statfricco = sco, kinfricco = kco);

  equation
    v = der(x);
    mass * der(v) = sfo - ffo;

  annotation(
      experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-8, Interval = 0.02),
      __OpenModelica_simulationFlags(lv = "LOG_STATS", outputFormat = "mat", s = "dassl"));

  end fricexample_1;

end friction1D;
Foad S. Farimani
  • 12,396
  • 15
  • 78
  • 193