5
$\begingroup$

I am trying to simulate a pulse width modulated signal in a NDSolve, but i have a hard time passing the signal function in. This is my code:

(* Arbitrary test circuit *)
components = {r iR[t] == vR[t], l iL'[t] == vL[t], iC[t] == c vC'[t]};
connections = {vR[t] + vL[t] + vC[t] - v1[t] == 0, 
               iL[t] == iR[t], iR[t] == iC[t]};
ic = {iR[0] == 0, iL[0] == 0, iC[0] == 0, vR[0] == 0, 
      vL[0] == 0, vC[0] == 0, iR'[0] == 0, iL'[0] == 0, 
      iC'[0] == 0, vR'[0] == 0, vL'[0] == 0, vC'[0] == 0};
params = {r -> 5, l -> 10^-2, c -> 10^-4};

signal = {1, 0.1, 0.1, 0.2, 0, 1, 0, 1, 0, 0.4, 0.4, 0, 
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

(* Problem in this definition*)
v1[t_] := If[
  Mod[t, 1/100]*100 > signal[[ IntegerPart[100.0*t + 1] ]]
  , 1, 0
];
(* solve does thus not work*)
sol = NDSolve[
        {components, connections, ic} /. params, 
        vC, {t, 0.0, 0.2}
    ];

I feel like i'm close but still so far away. The error seems to indicate that ...0,0,0,0,0,0,0,0,0}[[1/2]]] the error is in the Part lookup. How can this be im asking for the IntegerPart? Should i be using some other function for this. Tried wrapping a N in the expression.

Also any ideas how i could make the signal function smooth step would be great.

$\endgroup$

2 Answers 2

6
$\begingroup$
h[t_?NumericQ] := signal[[Floor[100*t + 1]]];
sol = NDSolveValue[{components, connections, ic,
          WhenEvent[Mod[t, 1/100]*100 - h[t] == 0, v1[t] -> Unitize[v1[t] - 1]]} /. 
          params, {vC, v1}, {t, 0.0, 0.2}, DiscreteVariables -> {v1}];
Plot[Through[sol[t]], {t, 0, .2}, Evaluated -> True]

Mathematica graphics


The above solution seems correct,but it isn't.

It is losing the last components of signal because of this behavior:

Plot[Mod[t, 1/100]*100 - h[t], {t, 0, .2}]

Mathematica graphics

The events lying on the red ellipse are not detected because the sign of the function and its derivative don't change. One simple (but not precise) way to get those too is:

h[t_?NumericQ] := signal[[Floor[100*t + 1]]];
sol = NDSolveValue[{components, connections, ic,
     WhenEvent[Mod[t, 1/100]*100 - h[t] - .05 == 0, v1[t] -> Unitize[v1[t] - 1]]} /. 
     params, {vC, v1}, {t, 0.0, 0.2}, DiscreteVariables -> {v1}];
Plot[Through[sol[t]], {t, 0, .2}, Evaluated -> True,  PlotPoints -> 1000]

Mathematica graphics

$\endgroup$
2
  • $\begingroup$ Actually there probably should not be a dip after a 0 pulse so consecutive zeroes should behave like in the first example. $\endgroup$
    – joojaa
    Jan 26, 2016 at 15:38
  • 1
    $\begingroup$ @joojaa Well ... you decide ... $\endgroup$ Jan 26, 2016 at 16:03
4
$\begingroup$

There are two problems in your code :

  • v1[t_] should be replaced by v1[t_?NumericQ] . The idea is to prevent NDSolve[..v1[t]...]to ask what is v1[t] with t purely symbolic. See for example this link.

  • Your system of equation contains equalities between variables without derivatives and thus is interpreted as a Differential-Algebric system. Mathematica uses also the DAE solver which is not adapted to this simple classical ODE system.

The hereafter solution is no more that a rewriting of the system with the minimum necessary 2 variables. It has the advantage of being compatible with your definition of v1 : v1[t] = If[Mod[t, 1/100]* ...))

ClearAll[v1];

(*Arbitrary test circuit*)
components = {r iR[t] == vR[t], l iL'[t] == vL[t], iC[t] == c vC'[t]};
connections = {vR[t] + vL[t] + vC[t] - v1[t] == 0, iL[t] == iR[t], 
   iR[t] == iC[t]};
ic = {iR[0] == 0, iL[0] == 0, iC[0] == 0, vR[0] == 0, vL[0] == 0, 
   vC[0] == 0, iR'[0] == 0, iL'[0] == 0, iC'[0] == 0, vR'[0] == 0, 
   vL'[0] == 0, vC'[0] == 0};
params = {r -> 5, l -> 10^-2, c -> 10^-4};

signal = {1, 0.1, 0.1, 0.2, 0, 1, 0, 1, 0, 0.4, 0.4, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0};

(* no more problems in this definition*)
v1[t_?NumericQ] := 
  If[Mod[t, 1/100]*100 > signal[[IntegerPart[100.0*t + 1]]], 1, 0];

(* rewriting of the problem with a minimal set of variables *)
newEqus = 
  Join[components, connections] // 
   Eliminate[#, {vL[t], vR[t], iR[t], iC[t]}] & ;

(* only two variables are remaining. Initial condition for these two
variables : *)
newIc = {iL[0] == 0, vC[0] == 0};

(*solution *)
sol = NDSolveValue[{newEqus, newIc} /. params, {vC, v1}, {t, 0.0, 
    0.2}];

Plot[Through[sol[t]], {t, 0, .2}, Evaluated -> True]  

enter image description here

$\endgroup$
1
  • $\begingroup$ Thanks, I've accepted Dr. belisarius answer, after some testing because it alerted me if event driving which is a good idea in general. Your answer is also very useful. Though you get slightly different results. $\endgroup$
    – joojaa
    Jan 26, 2016 at 11:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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