# Help needed to make NIntegrate Converge

I have the following notebook (trying to caclulate the pull-in voltage of a structure):

phi1 = b1 Cos[1.03855 x1] - b1 Cosh[1.03855 x1] + a1 Sin[1.03855 x1] -
a1 Sinh[1.03855 x1]

phi2 = b2 Cos[1.84683 x2] + d2 Cosh[1.84683 x2]

param = {b1 -> -0.255808, b2 -> 0.0340514, d2 -> 0.00305984, a1 -> 1,
c1 -> -1}

(*Numeric Constants*)
h = 2*10^-6;
wa = 10*10^-6;
la = 60*10^-6;
w = 100*10^-6;
l = 100*10^-6;
g = 1*10^-6;
e = 160*10^9;
epsilon0 = 8.85*10^-12;
sig0 = 0

i1 = wa*h^3/12;
i2 = w*h^3/12;
Area1 = h*wa;
Area2 = h*w;

θ = (Area2/Area1)^(1/4);
α = (i2/i1)^(1/4);
u = la/(l + la);
y = l/(l + la);

numericPhi1[x1_] = phi1 /. param
numericPhi2[x2_] = phi2 /. param

ph[x_] = Piecewise[{{numericPhi1[x],
0 <= x <= u}, {numericPhi2[1 - x], u < x <= 1}}];

ϕ[x_] :=
Piecewise[{{ph[x], 0 <= x <= 1}, {ph[2 - x], 1 < x <= 2}}];
b[x_?NumericQ] :=
Piecewise[{{wa, 0 <= x <= u}, {w, u < x <= 1}, {w,
1 < x <= 1 + (1 - u)}, {wa, 1 + (1 - u) < x <= 2}}]
i[x_?NumericQ] :=
Piecewise[{{i1, 0 <= x <= u}, {i2, u < x <= 1}, {i2,
1 < x <= 1 + (1 - u)}, {i1, 1 + (1 - u) < x <= 2}}]

nom[n_?NumericQ] :=
NIntegrate[(b[x] ϕ[x])/(g - n ϕ[x])^2, {x, 0, 2}]

denom[n_?NumericQ] :=
NIntegrate[(2 b[x] ϕ[x]^2)/(g - n ϕ[x])^3, {x, 0, 2}]


Now I try something simple:

nom[1.5]


If I do that I get the following warning:

NIntegrate::ncvb: NIntegrate failed to converge to prescribed accuracy after 9 recursive bisections in x near {x} = {0.00164274}. NIntegrate obtained 1.0191585739576856*^7 and 9.39610858946137*^6 for the integral and error estimates.

As you can see the error estimate is catastrophically huge 9.39610858946137*10^6, hence I do not trust the result.

As pointed out in the comments by @AccidentalFourierTransform, it might be due to my numeric constants, since they vary over large magnitudes. However, I cannot change those constants as they are fixed by the physics of the problem.

Any help would be very much appreciated !

• ph[x], phi[x], ...depend on a parameter u, which isn't defined! Perhaps that's the reason why the second errormessage occurs? – Ulrich Neumann Oct 9 '18 at 15:03
• nom[n], denom[n]are complex valued, is this intended? – Ulrich Neumann Oct 12 '18 at 9:14
• What is the meaning of parameter t? No value is assigned, I think that's the reason why the last integral p=...cannot be evaluated?? – Ulrich Neumann Oct 12 '18 at 9:19
• Something is obviously wrong with those Piecewise, what the hell is the {x, 0, 2}? – xzczd Oct 12 '18 at 15:20
• ……Please press F1 and check the document of Piecewise carefully. – xzczd Oct 12 '18 at 16:52

Some notes on debugging numerical solvers.

Singularities can cause all sorts of trouble with numerical routines. Sometimes it's not easy to tell whether your function has one if it has a complicated formula. Having a denominator as the OP's nom[] does, certainly should suggest the possibility, and it should be one of the first things a user investigates. Making a graph is a relatively cheap way to examine a function for potential singularities, at least for univariate or bivariate functions. @AccidentalFourierTransform has already pointed out that indeed singularities are at the root of the trouble with nom[1.5]. Aside from emphasizing the Make-A-Graph strategy, I want to show that there is a feasible domain for n and how to find it.

Make A Graph

The somewhat consistent syntax design of Mathematica makes this simple: Copy input (Cmd-L on a Mac), change the command (NIntegrate) to Plot, nix the options. In this case, we have to copy the code from nom and insert a value for n:

Plot[(b[x] ϕ[x])/(g - n ϕ[x])^2 /. n -> 1.5, {x, 0, 2}]


Well, we see part of the graph being cut off. So we have to extend the PlotRange:

Plot[(b[x] ϕ[x])/(g - n ϕ[x])^2 /. n -> 1.5, {x, 0, 2}, PlotRange -> All]


The spikes at or near x == 0, 2 might be vertical asymptotes (truncated by discrete sampling). The graph suggests there might be a problem

Analyzing the integrand

The integrand is a complicated combination of Piecewise functions that stumps Solve and gives NSolve some difficulty. One can get at the pieces in various ways. PiecewiseExpand will produce a single Piecewise function. Part 2 of each element of Part 1 of a Piecewise function yields the intervals for each piece and reveals the singularities where the pieces join:

PiecewiseExpand[(b[x] ϕ[x])/(g - n ϕ[x])^2][[1, All, 2]]
(*  {3/8 < x <= 1, 1 < x < 13/8, 13/8 < x <= 2, x == 13/8, 0 <= x <= 3/8}  *)


Passing these points to the numerical routine normally helps, when the function is otherwise well-behaved. For example, for feasible values of n, the following is faster than the OP's definition:

nom[n_?NumericQ] :=
NIntegrate[(b[x] ϕ[x])/(g - n ϕ[x])^2, {x, 0, 3/8, 1, 13/8, 2}];


We can get the expression for the denominator corresponding to the first singularity shown in the graph above using the second argument of PiecewiseExpand, which are assumptions to be applied in the expansion:

PiecewiseExpand[g - n ϕ[x], 0 < x < 3/8]
(*
1/1000000 - n (-0.255808 Cos[1.03855 x] + 0.255808 Cosh[1.03855 x]
+ Sin[1.03855 x] - Sinh[1.03855 x])
*)


This factor of the denominator is an analytic function and so has integer-order zeros. The denominator itself, being its square, has zeros of order 2 or higher (if it has any zero), which would not be integrable as @AccidentalFourierTransform has also pointed out. Where the factor is zero then determines whether function is integrable over {x, 0, 3/8}. It is similar for the other pieces.

Solving for n

The equation g - n ϕ[x] == 0 is difficult to solve for x but easy for n:

npw = n /. First@Solve[g - n ϕ[x] == 0, n] // PiecewiseExpand


We can see how the singularity at x depends on n by plotting the inverse relation:

Plot[npw, {x, 0, 2}, AxesOrigin -> {0, 0}, Frame -> True,
FrameLabel -> {x, n}]


The minimum value of n is at x == 1:

n0 = npw /. x -> 1
(*  0.000026946  *)


For values of n less than n0, the integral converges:

nom[0.9 n0]
nom[0]
nom[-1]
(*
1.5136*10^8
3.9056*10^6
0.0344148
*)

• Ah, really good analysis. I checked that there were singularities for any $n$ sufficiently large, but I didn't go to very small values (I think the minimal value I took was n = 0.0001). I jumped into conclusions too fast there, and you're right that for sufficiently small n, the singularities disappear. Nice! – AccidentalFourierTransform Oct 13 '18 at 21:56
• I did get the value of n0 = 0.000026 (cf. one of my comments below my answer), but my interpretation of that result was wrong: I realised that for that value the two singularities merge into one, but I thought that for smaller n they would separate again. Silly me, they disappear instead! – AccidentalFourierTransform Oct 13 '18 at 22:00
• @AccidentalFourierTransform I must have missed the significance of the comment (or missed the comment entirely). Thanks for the compliment. – Michael E2 Oct 13 '18 at 22:22

Your integral doesn't exist: the integrand has a non-integrable singularity in the integration region. This singularity is given by the solution of g == n ϕ[x]:

zero[n_] := FindRoot[g - n ϕ[x] == 0, {x, .002}][[1, 2]]


and the integrand diverges around this point, faster than $$x^{-2}$$:

With[{n = 1.5}, Plot[(g - n ϕ[x])^2/x^2, {x, .9 zero[n], 1.1 zero[n]}, PlotRange -> {Automatic, {-10^-8, 10^-8}}]]


(while the numerator of the integrand stays regular there).

This is the reason NIntegrate was not able to integrate your function. Your problem is ill-defined and has no solution, so you probably made a conceptual mistake somewhere.

(Actually, I now realise the integrand has two singularities, cf. the comment below; the integral is still ill-defined)

OP seems unconvinced the integral diverges. Let $$x_1,x_2$$ denote the two singularities, that is, the two solutions of g == n ϕ[x]. We can omit from the integral the intervals $$[x_1-\epsilon,x_1+\epsilon]$$ $$[x_2-\epsilon,x_2+\epsilon]$$ for some small $$\epsilon>0$$, thus rendering the integral well-defined:

zero1[n_] := FindRoot[g - n ϕ[x] == 0, {x, .002}][[1, 2]]
zero2[n_] := FindRoot[g - n ϕ[x] == 0, {x, 1.9}][[1, 2]]

nom[n_?NumericQ, ϵ_] := NIntegrate[(b[x] ϕ[x])/(g - n ϕ[x])^2, {x, 0, zero1[n] - ϵ}] +
NIntegrate[(b[x] ϕ[x])/(g - n ϕ[x])^2, {x, zero1[n] + ϵ, zero2[n] - ϵ}] +
NIntegrate[(b[x] ϕ[x])/(g - n ϕ[x])^2, {x, zero2[n] + ϵ, 2}];

denom[n_?NumericQ, ϵ_] := NIntegrate[(2 b[x] ϕ[x]^2)/(g - n ϕ[x])^3, {x, 0, zero1[n] - ϵ}] +
NIntegrate[(2 b[x] ϕ[x]^2)/(g - n ϕ[x])^3, {x, zero1[n] + ϵ, zero2[n] - ϵ}] +
NIntegrate[(2 b[x] ϕ[x]^2)/(g - n ϕ[x])^3, {x, zero2[n] + ϵ, 2}];


With this, we note that the numerator diverges as $$\epsilon^{-1}$$ as $$\epsilon\to0$$:

Show[LogLogPlot[num[n,ϵ], {ϵ, .00005, .1}], Plot[-x - 11, {x, -10, 1}, PlotStyle -> Orange]]


and so does the denominator (demostration left to the reader).

So, again: the integral doesn't exist. Not even as a Cauchy-principal value. (And even if it did, it would be hard to argue that a physical system requires that a regularisation in particular, which is non-unique and not really that special or natural).

Note: both the numerator and the denominator diverge as $$\epsilon^{-1}$$ as $$\epsilon\to0$$, so the quotient is well-defined in such a limit. But this regularisation does not seem to be physically justified to me, and I am almost positive OP made a mistake somewhere, so I don't want to encourage this approach.

• Hmm... what if you change the n? It might exist for a specific n, the one I am searching for. Have you seen the answer, I gave ? When I approximate the functions phi1 and phi2 using a fit, it seems to work, but I am not getting the correct result.. So you might be wright. However, i am not getting an error either.. – james Oct 13 '18 at 17:16
• @james The integrand has a singularity for any $n>0$. For $n\to0^+$ the singularity is around $x\to0^+$, and for $n\to+\infty$ the singularity is around $x\to 2^-$. This behaviour stays the same even if you use the approximate phi1, phi2. The integral does not exist, for any n, and regardless of whether you use the exact function or the Fit one. Maybe you made an algebraic mistake somewhere? Or n should be negative? – AccidentalFourierTransform Oct 13 '18 at 17:43
• In fact, it has a pair of singularities: one around $x\to0^+$, and one around $x\to 2^-$, for any $n$. As you decrease $n$, these two singularities get closer and they cross around $n=0.00002$. – AccidentalFourierTransform Oct 13 '18 at 18:00
• How do you see that the integral does not exist for any n ? – james Oct 13 '18 at 18:19
• @james No problem, I'm here to help. I chose n = 1.5 for illustration purposes (and because this is the value for n you used in the OP). But the behaviour is qualitatively the same for any value of n: the singularities move around, but they are still there. You could try to prove that g == n ϕ[x] has two solutions in the interval $x\in [0,2]$ for any $n>0$. I don't have a formal proof, but it is easy to check this numerically. I invite you to do it yourself. – AccidentalFourierTransform Oct 13 '18 at 18:33