# Forcing at least $n$ spatial steps in solving a 1D spatio-temporal PDE problem with NDSolve

I want to solve the telegraph equation with a spatial discretization forced at 200 points. I tried:

reg = Line[{{0}, {1}}];
shape = Cos[16 π (x - 0.5)] D[0.125 Erf[(x - 0.5)/0.125], x];
op = D[u[t, x], {x, 2}] - D[u[t, x], {t, 2}];
ics = {u[0, x] == shape, Derivative[1, 0][u][0, x] == 0};
sol = NDSolveValue[{op == 0, ics}, u, {t, 0, 2}, {x} ∈ reg, MaxStepSize -> 0.005];
Plot[shape, {x, 0, 1}, PlotRange -> All,Frame -> True]
Plot[sol[0, x], {x, 0, 1}, PlotRange -> {-1, 1.5}, Frame -> True]


The plots show that NDSolve has chosen 20 spatial points. My MaxStepSize option is used for the temporal variable t and not for the spatial variable x.

1. What is the NDSolve option or syntax for forcing 200 spatial points?

2. Where is this information in the NDSolve documentation?

3. Is there a NDSolve method that would have by default discretize more cleverly?

Edited question given the first answers that were posted:

1. How to force the initial spatial meshing at 200 points, keeping the region specification for x and consequently the finiteElement method ?
• related Feb 13 '19 at 20:21
• replacing NDSolve by NDSolveValue wouldn't help at all. Feb 13 '19 at 20:29
• Strange: I had not asked question 4 in my post... Feb 14 '19 at 9:30

shape = Cos[16 \[Pi] (x - 0.5)] D[0.125 Erf[(x - 0.5)/0.125], x];
op = D[u[t, x], {x, 2}] - D[u[t, x], {t, 2}];
ics = {u[0, x] == shape, Derivative[1, 0][u][0, x] == 0};
bc = {u[t, 0] == shape /. x -> 0, u[t, 1] == shape /. x -> 1};
sol = NDSolveValue[{op == 0, ics, bc}, u, {t, 0, 2}, {x, 0, 1},
Method -> {"MethodOfLines",
"SpatialDiscretization" -> {"TensorProductGrid",
"MinPoints" -> 200, "MaxPoints" -> 213,
"DifferenceOrder" -> "Pseudospectral"}}];
{Plot[shape, {x, 0, 1}, PlotRange -> All, Frame -> True],
Plot[sol[0, x], {x, 0, 1}, PlotRange -> {-1, 1.5}, Frame -> True]}

Plot3D[sol[t, x], {t, 0, 2}, {x, 0, 1}, Mesh -> None,
ColorFunction -> Hue] • Good. Thank you, but your NDSolve syntax makes me loose several things: 1) the method option is incompatible my x specification in a region: x \element reg. 2) So I loose the perfectly reflective boundary condition corresponding to the default zero neumann values when no boundary conditions are specified. 3) I loose the clever time integration with adaptive timesteps. I tried to keep my syntax and just add your method option I but get an error... Feb 14 '19 at 9:39
• @user3650925 I added boundary conditions compatible with the initial data. If you want other boundary conditions, then just use them (change bc). Feb 14 '19 at 12:15

Just to point out several issues.

The plots show that NDSolve has chosen 20 spatial points.

Well, I don't know why you think the plots show the number of grid points is 20, but you're wrong. The number of mesh coordinates (yeah the FiniteElement Method has been chosen for spatial discretization because of the {x} ∈ reg, check this post for more information ) can be checked by

coord = Flatten@sol["Coordinates"][]["Coordinates"] // Sort
(* {0., 0.025, 0.05, 0.075, 0.1, 0.125, 0.15, 0.175, 0.2, 0.225, 0.25, 0.275, 0.3,
0.325, 0.35, 0.375, 0.4, 0.425, 0.45, 0.475, 0.5, 0.525, 0.55, 0.575, 0.6, 0.625, 0.65,
0.675, 0.7, 0.725, 0.75, 0.775, 0.8, 0.825, 0.85, 0.875, 0.9, 0.925, 0.95, 0.975, 1.} *)

coord // Length
(* 41 *)


The next important issue is boundary condition (b.c.). I'm not sure why you don't add b.c. to the system, but you're wrong again if you think NDSolveValue will be forced to solve an initial value problem (IVP) i.e. a problem defined in $$x \in (-\infty,\infty)$$. The b.c. at $$x=0$$ and $$x= 1$$ is Neumann 0 condition i.e. NeumannValue[0,…] in this case, for more information check the Details section of document of NeumannValue. If you need to approximate infinity, consider starting from this post.

Finally I'd like to add, it's possible to use MaxStepSize to control grid size in $$x$$ direction if TensorProductGrid method is used for spatial discretization. We just need to use a List as the option value, here is an example. Nevertheless, I don't recommend using this method to control spatial grid, because there's no MinStepSize for NDSolve. (The MinStepSize option mentioned in e.g. NDSolveValue::mxsst warning is an option for TensorProductGrid method. )

• Thank you.Sorry for the sentence "The plots show that NDSolve has chosen 20 spatial points." I should have said "The plots show that NDSolve has chosen an insufficient number of spatial points." Concerning the bc, I want the default bc taken by NDSolve when you specifiy the saptial coordiantes by a region, i.e. 0 Neumann values. In other worfd, the bc are hidden, but are well defined and correspond to what I want. I now study your links. Thank you again. Feb 14 '19 at 9:43

The answer I was looking for is the following: Add a Method option in NDSolve that is compatible with the method that NDSolve chooses by itself given your PDEs syntax. Then add your discretization specification in the sub-options. Here, the solution is:

NDSolveValue[{op == 0, ics}, u, {t, 0, 2}, {x} \[Element] reg,
Method -> {"FiniteElement", "MeshOptions" -> {"MaxCellMeasure" -> 0.005}}]


With and without the Method option the final result is either correct (regeneration of the shape at time t=2, after two reflections on the region boundaries), or completely False:  Now, there is a correlative question: In the solution above I specify the stepsize manually to get sufficient meshing and a correct solution. A much better solution would be to force NDSolve to check the validity of its solution and refine the spatial stepsize by itself... I create a separate post for this question.

• I think this is the correct way to go. Feb 14 '19 at 10:47