rreusser / ndarray-transfinite-interpolation

[WIP] Fill an n-dimensional array by interpolating functions that define the boundaries

Home Page:https://rreusser.github.io/ndarray-transfinite-interpolation/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ndarray-transfinite-interpolation

Fill an n-dimensional array by interpolating functions that define the boundaries

experimental

Introduction

Given a set of functions bounding a domain (as well as internal contours, if desired), this module fills an ndarray with an n-dimensional mesh. Its primary use is for creating computational grids.

Example

To create a planar mesh in two dimensions, specify functions defining the four edges. Each of the four edges is defined by a function of one variable. The easiest way to remember the sequence is as ordered pairs of opposing edges, the first set with u ommitted, then v.


Try it out (click button to edit on codepen) →

var tfi = require('ndarray-transfinite-interpolation');
var zeros = require('ndarray-scratch').zeros;

var edges = [[
  v => [0, v],
  v => [1, v]
], [
  u => [u, 0],
  u => [u, 1]
]];

tfi(zeros([11, 11, 2]), edges);

You can perturb the edges with functions:


Try it out →

tfi(zeros([11, 11, 2]), [[
  v => [Math.sin(v * Math.PI * 2), v],
  v => [1, v]
], [
  u => [u, 0],
  u => [u, 1]
]]);

Now we can get creative. So far we've defined edges, but you can also define internal curves through which the grid passes.


Try it out →

tfi(zeros([11, 11, 2]), [[
  v => [Math.sin(v * Math.PI * 2), v],
  v => [0.5, v],
  v => [1, v]
], [
  u => [u, 0],
  u => [u, 1]
]]);

Notice that although we've defined a straight line through the center, the grid on the righthand side is slightly perturbed in the opposite direcdtion. That's because of the Lagrange interpolation. A future version will include the option to use linear interpolation instead.

By passing an additional array of arrays, you can specify the parameter values at which the respective curves are defined:


Try it out →

const edges = [[
  v => [0, v],
  v => [1, v]
], [
  u => [u, 0],
  u => [u, 0.2],
  u => [u, 1]
]];

const t = [[0, 1], [0, 0.2, 1]]

const A = tfi(zeros([11, 11, 2]), edges, t);

Finally you can pass functions that map [0, 1] ⟶ [0, 1] or else an ndarray or array of matching length that defines the parameter values at which the respective curves are evaluated:


Try it out →

const edges = [
  [v => [0, v], v => [1, v]],
  [u => [u, 0], u => [u, 1]]
];

const mapping = [
  u => u * u * u,
  [0, 0.15, 0.2, 0.35, 0.4, 0.55, 0.6, 0.75, 0.8, 0.95, 1]
];

const A = tfi(zeros([11, 11, 2]), edges, null, mapping);

There's no reason to constrain things to two dimensions. You can interpolate a surface in three dimensions:


Try it out →


So far we've done surfaces in two or three dimensions. To create a volumetric mesh in three dimensions, imagine a cube parameterized by [u, v, w], with u ∈ [0, 1], v ∈ [0, 1], and w ∈ [0, 1]. Each of the six faces is defined by a two-dimensional function. The input to transfinite interpolation is these functions. The easiest way to conceptualize it is as ordered pairs of opposing faces, the first set with u ommitted, then v, then finally with w ommitted.


Try it out →

var faces = [[
    (v, w) => [0, v, w],
    (v, w) => [1, v, w]
  ], [
    (u, w) => [u, 0, w],
    (u, w) => [u, 1, w]
  ], [
    (u, v) => [u, v, 0],
    (u, v) => [u, v, 1]
]];

tfi(zeros([11, 11, 11, 3]), faces);

Get fancy. One thing to watch for is that it's very easy to define curves that don't actually meet where they claim to. If they don't match up, you'll still get a decent result, but it might not be what you expect.


Try it out →

Install

Not yet on npm. Useful, but needs cleanup.

API

require('ndarray-transfinite-interpolation')(grid, bounds[, t[, ivars]])

Fill ndarray grid with an evaluation of the specified grid. Options are:

  • grid: An ndarray into which the mesh is evaluated
  • bounds: An array of arrays containing for each dimension a list of functions that define the mesh. The trailing dimension of grid is expected to equal the number of dimensions (equal the length of the array) in bounds. Each function is parameterized from 0 to 1 and is expected to return an Array with length equal to the trailing dimension of grid.
  • t: An array of arrays specifying the respective value of the parameter at which bounds are defined. See above for illustration.
  • ivars: Independent variables at which to evaluate the grid into grid. These maybe be a function that maps [0, 1] → [0, 1] or else a one-dimensional array (or ndarray) of length equal to the corresponding dimension of grid. If not specified, the grid is evaluated with uniform spacing from 0 to 1.

To do

  • option for linear interpolation (instead of Lagrange interpolation)
  • boundary derivative
  • lots of tests!

See also

License

© 2016 Ricky Reusser. MIT License.

About

[WIP] Fill an n-dimensional array by interpolating functions that define the boundaries

https://rreusser.github.io/ndarray-transfinite-interpolation/


Languages

Language:JavaScript 98.8%Language:CSS 1.2%