I used the method of solving integro-differential equations proposed by Michael E2 on Solving an integro-differential equation with Mathematica
I added new options to his code to solve this problem. The right figure in Figure 1 corresponds to Figure 1 of the article Viscous Flow at Infinite Marangoni Number by A. Thess, D. Spirn, and B. Juttner - see journals.aps.org/prl/pdf/10.1103/PhysRevLett.75.4614
L = Pi; tmax = 1.;
sys = {D[u[x, t], t] + 1/(Pi)*int[u[x, t], x, t]*D[u[x, t], x] == 0,
u[-L, t] == u[L, t], u[x, 0] == -Cos[x]};
periodize[data_] :=
Append[data, {N@L, data[[1, 2]]}];(*for periodic interpolation*)
Block[{int},(*the integral*)
int[u_, x_?NumericQ, t_ /; t == 0] := (cnt++;
NIntegrate[-Cos[xp]/ (x - xp), {xp, x - L, x, x + L},
Method -> {"InterpolationPointsSubdivision",
Method -> "PrincipalValue"}, PrecisionGoal -> 8,
MaxRecursion -> 20, AccuracyGoal -> 20] // Quiet);
int[uppp_?VectorQ, xv_?VectorQ, t_] := Function[x, cnt++;
NIntegrate[
Interpolation[periodize@Transpose@{xv, uppp}, xp,
PeriodicInterpolation -> True]/ (x - xp), {xp, x - L, x,
x + L}, Method -> {"InterpolationPointsSubdivision",
Method -> "PrincipalValue"}, PrecisionGoal -> 8,
MaxRecursion -> 20] (*adjust to suit*)] /@ xv // Quiet;
(*monitor while integrating pde*)Clear[foo];
cnt = 0;
PrintTemporary@Dynamic@{foo, cnt, Clock[Infinity]};
(*broken down NDSolve call*)
Internal`InheritedBlock[{MapThread}, {state} =
NDSolve`ProcessEquations[sys, u, {x, -L, L}, {t, 0, tmax},
StepMonitor :> (foo = t),
Method -> {"MethodOfLines",
"SpatialDiscretization" -> {"TensorProductGrid",
"MinPoints" -> 41, "MaxPoints" -> 81,
"DifferenceOrder" -> 2}}];
Unprotect[MapThread];
MapThread[f_, data_, 1] /; ! FreeQ[f, int] := f @@ data;
Protect[MapThread];
NDSolve`Iterate[state, {0, tmax}];
sol = NDSolve`ProcessSolutions[state]]] // AbsoluteTiming
{Plot3D[u[x, t] /. sol, {x, -Pi, Pi}, {t, 0., 1.}, Mesh -> None,
ColorFunction -> Hue, AxesLabel -> Automatic] // Quiet,
Plot[Evaluate[Table[u[x, t] /. sol, {t, 0., 1., .2}]], {x, -Pi,
Pi}] // Quiet}
For this equation, we can apply another solution method by decomposing the desired function in a Fourier series:
u= Sum[f[m][t] Exp[I m x], {m, -Infinity, Infinity}]
Then the integral is exactly calculated for each mode. As a result, we find the system of equations and the numerical model
nn = 137; tm = 1.2; eq =
Table[f[m]'[t] -
Sum[ If[Abs[m - k] <= nn, (k - m) f[m - k][t], 0] Sign[k] f[k][
t], {k, -nn, nn}] == 0, {m, -nn, nn}];
ic = Table[
f[m][0] == (KroneckerDelta[m, 1] + KroneckerDelta[m, -1])/
2, {m, -nn, nn}];
var = Table[f[i], {i, -nn, nn}];
sol1 = NDSolveValue[{eq, ic}, var, {t, 0, tm}];
{Plot[Evaluate[
Table[Re[
Sum[sol1[[m + 1]][t] Exp[I (-nn + m) x], {m, 0, 2*nn}]], {t, 0,
tm, .2}]], {x, 0, 2*Pi}, Mesh -> None, ColorFunction -> Blue,
AxesLabel -> Automatic, PlotLegends -> Automatic],
Plot3D[Re[
Sum[sol1[[m + 1]][t] Exp[I (-nn + m) x], {m, 0, 2*nn}]], {t, 0.,
tm}, {x, 0, 2*Pi}, Mesh -> None, ColorFunction -> Hue,
AxesLabel -> Automatic]}
The results of calculations for the two models are the same, but the second model takes less time. So, for example, 341 seconds were spent on the test example for the first model, and only 0.49 seconds for the second model (on my laptop).