Skip to main content

differential equations - Problem with numerical solution of a system of ODEs


Background


Good evening, I have a big problem with num. solution NDSolve of differential equation. To start with, the model:


There is a fast-moving rope in closed path. Where


$T$ is tension,


$a$ is angle beetwen rope and horizontal plane,



$s$ is curvilinear coordinates $[0,1]$ ($0$ - the beginning of the rope, $1$ - the ending of the rope).


$Dr$ drag coefficient


$W$ weight coefficient


And it gives the differential equations for $T$, $a$ and $s$.


$$\frac{d}{ds}(T(s)\sin\alpha(s))=W+Dr\sin\alpha(s) $$


$$\frac{d}{ds}(T(s)\cos\alpha(s))=Dr\cos\alpha(s) $$


D[T[s] Sin[a[s]], s] == W + Dr Sin[a[s]], 
D[T[s] Cos[a[s]], s] == Dr Cos[a[s]],

Moreover, boundary conditions comes from equation for beginning and ending of the rope. $x[0] = x[1] = 0, y[0] = y[1] = 0$, where $x[s]$, $y[s]$ are coordinates of point on the rope with curve distance to beginning $s$. It means, that ending and beginning of the rope are in the same place. Differential equations for coodinates $x[s],y[s]$ are quite easy.



$$\frac{dy(s)}{ds}=\frac{\tan \alpha(s)}{\sqrt{1+\tan^2 \alpha(s)}} $$


$$\frac{dx(s)}{ds}=\frac{1}{\sqrt{1+\tan^2 \alpha(s)}} $$


(Tan[a[s]])/Sqrt[1 + Tan[a[s]]^2] == D[y[s], s],
1/Sqrt[1 + Tan[a[s]]^2] == D[x[s], s],
x[0] == 0,
y[0] == 0,
x[1] == ϵ,
y[1] == ϵ

I've solved it, but solution is unreal and contradicts boundary conditions. But Mathematica's solution in ParametricPlot looks like this:



**Fig.1** Obtained soltion


Fig.1 Obtained soltion


The rope should be closed, but it's not. And it should look like that:


**Fig.2** Shape of rope in dependence of Dr/W


Fig.2 Shape of rope in dependence of $\frac{Dr}{W}$


Please, help. The final code:


x[s] =.
y[s] =.
NumSol = Block[{\[Epsilon] = $MachineEpsilon},
With[{Dr = 9.9, W = 8},

NDSolve[{
D[T[s] Sin[a[s]], s] == W + Dr Sin[a[s]],
D[T[s] Cos[a[s]], s] == Dr Cos[a[s]],
(Tan[a[s]])/Sqrt[1 + Tan[a[s]]^2] == D[y[s], s],
1/Sqrt[1 + Tan[a[s]]^2] == D[x[s], s],
x[\[Epsilon]] == 0,
y[\[Epsilon]] == 0,
x[1 - \[Epsilon]] == \[Epsilon],
y[1 - \[Epsilon]] == \[Epsilon]
},

{T, a, x, y}, {s, \[Epsilon], 1 - \[Epsilon]},
Method -> {"StiffnessSwitching", "NonstiffTest" -> False}]]]

ParametricPlot[{x[s], y[s]} /. NumSol // Evaluate, {s, 0, 1},
PlotRange -> Automatic,
AspectRatio -> 1,
AxesLabel -> {"x", "y"}
]

Answer



Answer has been significantly revised



Begin by obtaining symbolic solutions for T[s] and a[s].


sat = DSolveValue[{D[T[s] Sin[a[s]], s] == W + Dr Sin[a[s]], 
D[T[s] Cos[a[s]], s] == Dr Cos[a[s]]}, {a[s], T[s]}, s]

but the result is a bit lengthy to reproduce here. However, simpler expressions can be extracted from sat for a[s]


eqa = Simplify[sat[[1, 1]] /. C[1] -> W*C[1]] == 
Simplify[sat[[1, 0, 1]][a[s]] /. Dr -> r*W]
(* s/C[1] + C[2] == ((Cos[a[s]/2] - Sin[a[s]/2])^(-1 - r)
(Cos[a[s]/2] + Sin[a[s]/2])^(-1 + r) (r - Sin[a[s]]))/(-1 + r^2) *)


where r = Dr/W has been introduced for compactness. T[s]also can be obtained in terms of a[s], although it is not needed for the computation below.


eqT = FullSimplify[sat[[2]] /. {sat[[1]] -> a[s], Dr -> r*W}]
(* C[1] Sec[a[s]] (Cos[a[s]/2] - Sin[a[s]/2])^(-r) (Cos[a[s]/2] + Sin[a[s]/2])^r *)

Analyzing eqa, we see that it is valid for RealC[_] only when - Pi/2 < a[s] < Pi/2. But, based on the reference provided by the OP in a comment above, - Pi/2 < a[s] < - 3 Pi/2 also is needed to solve the problem posed in the question. The latter solution can be obtained by the substitution a[s] -> Pi - a[s]and renormalization of C[1]. Combine the two.


eqaext = eqa[[1]] == Piecewise[{{eqa[[2]], a[s] > -Pi/2}, 
{-Simplify[eqa[[2]] /. a[s] -> Pi - a[s]], a[s] < -Pi/2}}, 0]
(* s/C[1] + C[2] == Piecewise[{{((Cos[a[s]/2] - Sin[a[s]/2])^(-1 - r)*
(Cos[a[s]/2] + Sin[a[s]/2])^(-1 + r)*(r - Sin[a[s]]))/(-1 + r^2), a[s] > -Pi/2},
{-(((-Cos[a[s]/2] + Sin[a[s]/2])^(-1 - r)*(Cos[a[s]/2] + Sin[a[s]/2])^(-1 + r)*

(r - Sin[a[s]]))/(-1 + r^2)), a[s] < -Pi/2}}, 0] *)

Note that the constants, C[_] may not be the same above and below a[s] = - Pi/2. In fact, determining C[_] is the essence of the computation. Here is a plot of eqaext[[2]] for r = 9.9/8, the value employed in the question.


ParametricPlot[{Last[eqaext /. {a[s] -> b, r -> 9.9/8}], b}, 
{b, -3 Pi/2 + .01, Pi/2 - 0.01}, AxesLabel -> {"s/c1+c2", "a[s]"},
ImageSize -> Large, LabelStyle -> {15, Black, Bold}, AspectRatio -> 1]

enter image description here


A numerical expression fora[s] as a function of Last[eqaext /. r -> 9.9/8} can be obtain readily by


int = Interpolation[Table[{Re[Last[eqaext /. {a[s] -> b, r -> 9.9/8}]], b}, 

{b, -3 Pi/2 + .0001, Pi/2 - .0001, .0001}]];

Surprizingly, this simple result is rather more robust than InverseFunction for the integrations that follow.


The specific problem that the code in the question attempts to address is equivalent to the respective C[_] being the same throughout - 3 Pi/2 < a[s] < Pi/2. To determine these two constants, require that {x[s], y[s]} both are equal to zero at s = 0 and s = 1, in other words that fi[c1, c2] = {0,0}, where


fi[c1_, c2_] := {NIntegrate[Cos[int[s/c1 + c2]], {s, 0, 1}], 
NIntegrate[Sin[int[s/c1 + c2]], {s, 0, 1}]}

which is solved by


param = FindRoot[Quiet@fi[c10, c20], {{c10, -.7}, {c20, .6}}, 
Evaluated -> False] // Values

Quiet[fi @@ %]
(* {-0.0909828, 5.49556} *)
(* {-1.13858*10^-16, 6.41848*10^-17} *)

Finally, a plot of x[t] and y[t] is obtained from


ps = ParametricNDSolveValue[{x'[s] == Cos[int[s/c1 + c2]], 
y'[s] == Sin[int[s/c1 + c2]], x[0] == 0, y[0] == 0},
{x[s], y[s]}, {s, 0, 1}, {c1, c2}];
ps @@ param;
ParametricPlot[%, {s, 0, 1}, AxesLabel -> {"x", "y"},

ImageSize -> Large, LabelStyle -> {15, Black, Bold}]

enter image description here


For completeness, a[0] is given by


int[param // Last]
(* 0.940888 *)

Let us turn now to reproducing a curve like those in the second figure in the question, for which a[0] is specified to be zero. Then, C[_] definitely are not the same above and below a[s] = - Pi/2. The four seemingly undetermined constants are reduced to two as follow. At s = 0.


c2p = Last[eqaext /. {a[s] -> 0, r -> 9.9/8}]
(* 2.32873 *)


Next, note that s must be continuous at a[s] = - Pi/2, which in turn requires that c1p*c2p = c1m*c2m. (Constants with names ending in p are for - Pi/2 < a[s], and with m for - Pi/2 > a[s].) This reduces the number of free constants to two, as desired. As before, determine them by requiring that {x[s], y[s]} both are equal to zero at s = 0 and s = 1.


f0[c1p_, c1m_] := {NIntegrate[Piecewise[{{Cos[int[s/c1p + c2p]], s < -c1p*c2p}, 
{Cos[int[s/c1m + c2p*c1p/c1m]], s > -c1p*c2p}}, 0], {s, 0, 1}],
NIntegrate[Piecewise[{{Sin[int[s/c1p + c2p]], s < -c1p*c2p},
{Sin[int[s/c1m + c2p*c1p/c1m]], s > -c1p*c2p}}, 0], {s, 0, 1}]}

param = FindRoot[Quiet@f0[c1p0, c1m0], {{c1p0, -.1}, {c1m0, -.01}},
Evaluated -> False] // Values
Quiet[f0 @@ %]

(* {-0.21471, -0.0133781} *)
(* {4.17224*10^-17, -9.19403*10^-17} *)

Finally, a plot of x[t] and y[t] is obtained from


ps0 = ParametricNDSolveValue[{x'[s] == Piecewise[{{Cos[int[s/c1p + c2p]], 
s < -c1p*c2p}, {Cos[int[s/c1m + c2p*c1p/c1m]], s > -c1p*c2p}}, 0],
y'[s] == Piecewise[{{Sin[int[s/c1p + c2p]],
s < -c1p*c2p}, {Sin[int[s/c1m + c2p*c1p/c1m]], s > -c1p*c2p}}, 0],
x[0] == 0, y[0] == 0}, {x[s], y[s]}, {s, 0, 1}, {c1p, c1m}];
ps0 @@ param;

ParametricPlot[%, {s, 0, 1}, AxesLabel -> {"x", "y"},
ImageSize -> Large, LabelStyle -> {15, Black, Bold}]

enter image description here


which fits well between the r = 1 and r = 1.5 curves in the second figure of the question. Generating all the curves in the second figure would be straightforward.


Comments

Popular posts from this blog

plotting - Filling between two spheres in SphericalPlot3D

Manipulate[ SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, Mesh -> None, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], {n, 0, 1}] I cant' seem to be able to make a filling between two spheres. I've already tried the obvious Filling -> {1 -> {2}} but Mathematica doesn't seem to like that option. Is there any easy way around this or ... Answer There is no built-in filling in SphericalPlot3D . One option is to use ParametricPlot3D to draw the surfaces between the two shells: Manipulate[ Show[SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], ParametricPlot3D[{ r {Sin[t] Cos[1.5 Pi], Sin[t] Sin[1.5 Pi], Cos[t]}, r {Sin[t] Cos[0 Pi], Sin[t] Sin[0 Pi], Cos[t]}}, {r, 1, 2 - n}, {t, 0, Pi}, PlotStyle -> Yellow, Mesh -> {2, 15}]], {n, 0, 1}]

plotting - Plot 4D data with color as 4th dimension

I have a list of 4D data (x position, y position, amplitude, wavelength). I want to plot x, y, and amplitude on a 3D plot and have the color of the points correspond to the wavelength. I have seen many examples using functions to define color but my wavelength cannot be expressed by an analytic function. Is there a simple way to do this? Answer Here a another possible way to visualize 4D data: data = Flatten[Table[{x, y, x^2 + y^2, Sin[x - y]}, {x, -Pi, Pi,Pi/10}, {y,-Pi,Pi, Pi/10}], 1]; You can use the function Point along with VertexColors . Now the points are places using the first three elements and the color is determined by the fourth. In this case I used Hue, but you can use whatever you prefer. Graphics3D[ Point[data[[All, 1 ;; 3]], VertexColors -> Hue /@ data[[All, 4]]], Axes -> True, BoxRatios -> {1, 1, 1/GoldenRatio}]

plotting - Adding a thick curve to a regionplot

Suppose we have the following simple RegionPlot: f[x_] := 1 - x^2 g[x_] := 1 - 0.5 x^2 RegionPlot[{y < f[x], f[x] < y < g[x], y > g[x]}, {x, 0, 2}, {y, 0, 2}] Now I'm trying to change the curve defined by $y=g[x]$ into a thick black curve, while leaving all other boundaries in the plot unchanged. I've tried adding the region $y=g[x]$ and playing with the plotstyle, which didn't work, and I've tried BoundaryStyle, which changed all the boundaries in the plot. Now I'm kinda out of ideas... Any help would be appreciated! Answer With f[x_] := 1 - x^2 g[x_] := 1 - 0.5 x^2 You can use Epilog to add the thick line: RegionPlot[{y < f[x], f[x] < y < g[x], y > g[x]}, {x, 0, 2}, {y, 0, 2}, PlotPoints -> 50, Epilog -> (Plot[g[x], {x, 0, 2}, PlotStyle -> {Black, Thick}][[1]]), PlotStyle -> {Directive[Yellow, Opacity[0.4]], Directive[Pink, Opacity[0.4]],