One can use generate an ElementMesh
once and for all (15-16 sec.); then use ElementMeshInterpolation
on each coordinate to construct interpolations (1.7 sec.).
Needs["NDSolve`FEM`"]
SeedRandom[0];
inputlist = RandomReal[{-10, 10}, {200000, 3}];
outputlist = RandomReal[{-10, 10}, {200000, 3}];
( mesh = DelaunayMesh[inputlist];
elem = Thread[MeshCells[mesh, 3], Tetrahedron] /.
Tetrahedron -> TetrahedronElement;
(*coords = MeshCoordinates[mesh];
coords == inputlist*)
emesh = ToElementMesh[
"Coordinates" -> inputlist,
"MeshElements" -> {elem}];
) // AbsoluteTiming
ifns = ElementMeshInterpolation[{emesh}, #,
"ExtrapolationHandler" -> {Indeterminate &,
"WarningMessage" -> False}] & /@
Transpose[outputlist]; // AbsoluteTiming
(*
{15.7423, Null}
{1.69745, Null}
*)
One can construct various interfaces to the interpolating functions. The matrix one is faster on lists of points, though only by a little.
Clear[ifn];
ifn[v_?VectorQ] := Through[ifns @@ v];
ifn[m_?MatrixQ] := Through[ifns @@ Transpose[m]];
ifn[x_?NumericQ, y_?NumericQ, z_?NumericQ] := Through[ifns[x, y, z]];
Evaluating the interpolating function is not fast, but I assume that is probably true no matter what. (An unstructured grid is handle by an ElementMesh
under the hood, AFAIK.) In any case, constructing emesh
only once saves a lot of time. I also am getting a small error with my last iteration. (There wasn't any the first time I tried.)
ifn@inputlist[[;; 10]] - outputlist[[;; 10]] // Abs // Max // AbsoluteTiming
(* {0.584745, 1.06581*10^-14} *)
But there doesn't seem to be a problem with the data in the interpolating functions:
Table[
{ifns[[i]]["ElementMesh"]["Coordinates"] == inputlist,
ifns[[i]]["ValuesOnGrid"] == outputlist[[All, i]]}, {i, 3}]
(* {{True, True}, {True, True}, {True, True}} *)
I suppose it's a weakness in the internal interpolating code.
NDSolve`FEM`ElementMeshInterpolation
. $\endgroup$inputlist=RandomReal[{-10, 10}, {200000, 3}]
andoutputlist=RandomReal[{-10, 10}, {200000, 3}]
(in these example boundaries may be different, but in my case they are equal). Both lists represent unstructured grid. Another list contains data in the inputlist at different timesteps (example):Temp=RandomInteger[{100,200},{200000,1000}]
. I made a loop withTempFunc = Interpolation[DataTable, InterpolationOrder -> 1]
function, whereDataTable=MapThread[List, {inputlist, Temp[[istep]]}]
. $\endgroup$NDSolve
FEMElementMeshInterpolation
helps. Becomes x4 faster. $\endgroup$