Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

The problem is $$ x''(t)=F(t) - kx'(t) \\ x'(0)=x(0)=0$$ with the additional constraints $$ 0 < x(t) <a \\ 0 < x'(t) <b $$ where $F(t)$ is a known function and $a,b,k$ are given. At the moment I solve such problems with the help of WhenEvent[...].

Example:

First@First@NDSolve[{
  x''[t] == 10 Sin[0.1 t] - 0.1 x'[t], x[0] == 0, 
  x'[0] == 0, WhenEvent[x[t] > 400, x[t] -> 399], 
  WhenEvent[x'[t] > 40, x'[t] -> 39], 
  WhenEvent[x[t] < 0, x[t] -> 1], 
  WhenEvent[x'[t] < -40, x'[t] -> -39]}, 
 x, {t, 0, 200}, 
 MaxSteps -> 50000];
Plot[{x[t] /. %, 10 x'[t] /. %}, {t, 0, 200}, PlotRange -> All, 
 PlotLegends -> {"x[t]", "x'[t]"}, ImageSize -> 700]

Plot of x, x'

What is the proper way to solve this type of problem?

share|improve this question
    
It's doing what it's specified to my understanding. Do you want the variables to remain at boundaries until force changes direction? Do you want perhaps the force to change direction upon hitting constraints? In that case you must introduce force as additional (discrete) variable in the equations of NDSolve. –  BoLe Jun 2 '13 at 15:44
    
BoLe, yes, I want the variables to remain at boundaries until force changes direction. –  Kamov Sergey Jun 2 '13 at 15:55
    
I did something for x[t], try and stretch that to x'[t]. –  BoLe Jun 2 '13 at 17:05
add comment

1 Answer 1

up vote 2 down vote accepted

I guess that can be done. I don't know if you'll love this solution though.

{s, a} = NDSolveValue[{
   x''[t] == alive[t] 10 Sin[0.1 t] - 0.1 x'[t],
   x[0] == 0, x'[0] == 0,
   alive[0] == 1,
   speed[0] == 0,
   WhenEvent[x[t] > 400, {
     speed[t] -> x'[t], x'[t] -> 0, alive[t] -> 0}],
   WhenEvent[Sin[.1 t] < 0, {
     x'[t] -> -speed[t], alive[t] -> 1}],
   WhenEvent[x[t] < 0, {
     speed[t] -> x'[t], x'[t] -> 0, alive[t] -> 0}],
   WhenEvent[Sin[.1 t] > 0, {
     x'[t] -> -speed[t], alive[t] -> 1}]},
  {x, alive},
  {t, 0, 100},
  DiscreteVariables -> {alive, speed}]

Roughly, I stored the first derivative and temporarily killed it together with force and then restored both at the appropriate moment.

Plot[{s[t], 300 a[t]},
 {t, 0, 100},
 PlotRange -> All,
 PlotStyle -> Thick]

plot

share|improve this answer
    
Thank you very much for your reply! It works, but I have 18 variables with constraints so it will be very hard. –  Kamov Sergey Jun 2 '13 at 17:18
    
@KamovSergey If the constraints form a pattern of some sort you can encode you might want to look how to automate equations (WhenEvent is part of equation). You can do that. See help on WhenEvent, then Applications > Bouncing Balls. Or you could MapThread over the specification matrix. It shouldn't be hard to set up the whole problem elegantly I think. –  BoLe Jun 2 '13 at 17:34
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.