Минимальное поверхностное решение в Python

У меня есть набор трехмерных точек, определяющих трехмерный контур. Я хочу получить минимальное представление поверхности, соответствующее этому контуру (см. Минимальные поверхности в Википедии) . В основном это требует решения нелинейного уравнения в частных производных.

В Matlab это почти просто использовать pdenonlinфункцию (см. Документацию Matlab). Пример его использования для решения проблемы с минимальной поверхностью можно найти здесь: Минимальные проблемы с поверхностью на блочном диске.

Мне нужно сделать такую ​​реализацию на Python, но, насколько мне известно, я не нашел никаких веб-ресурсов о том, как это сделать.

Может ли кто-нибудь указать мне какие-либо ресурсы / примеры такой реализации?

Спасибо, Мигель.

ОБНОВЛЕНИЕ

Трехмерная поверхность (в идеале треугольная сетка), которую я хочу найти, ограничена этим набором трехмерных точек (как видно на этом рисунке, точки лежат в наиболее подходящей плоскости):

введите описание изображения здесь

Итак, проведя небольшое исследование, я обнаружил, что эта минимальная поверхностная проблема связана с решением Бигармонического уравнения, и я также обнаружил, что Тонкопластинчатый шлиц является фундаментальным решением этого уравнения.

Поэтому я думаю, что подход будет заключаться в том, чтобы попытаться подогнать это разреженное представление поверхности (заданное трехмерным контуром точек) с помощью шлицев из тонких пластин. Я нашел этот пример в scipy.interpolate где разрозненные данные (формат x, y, z) интерполируются с использованием шлицев тонких пластин для получения координат ZI на однородной сетке (XI, YI).

Возникают два вопроса: (1) Будет ли сплайн-интерполяция тонкой пластины правильным подходом к проблеме вычисления поверхности по набору точек трехмерного контура? (2) Если да, то как выполнить интерполяцию тонкой пластины на scipy с НЕОДНОРОДНОЙ сеткой?

Спасибо еще раз! Мигель

ОБНОВЛЕНИЕ: РЕАЛИЗАЦИЯ В MATLAB (НО НЕ РАБОТАЕТ НА SCIPY PYTHON)

Я подписался на этот пример с помощью tpaps функции Matlab и получил минимальную поверхность, подходящую к моему контуру на однородной сетке. Это результат в Matlab (выглядит отлично!): введите описание изображения здесь

Однако мне нужно реализовать это на Python, поэтому я использую пакет scipy.interpolate.Rbf и функцию thin-plate. Вот код на python (XYZ содержит трехмерные координаты каждой точки контура):

GRID_POINTS = 25
x_min = XYZ[:,0].min()
x_max = XYZ[:,0].max()
y_min = XYZ[:,1].min()
y_max = XYZ[:,1].max()
xi = np.linspace(x_min, x_max, GRID_POINTS)
yi = np.linspace(y_min, y_max, GRID_POINTS)
XI, YI = np.meshgrid(xi, yi)

from scipy.interpolate import Rbf
rbf = Rbf(XYZ[:,0],XYZ[:,1],XYZ[:,2],function='thin-plate',smooth=0.0)
ZI = rbf(XI,YI)

Однако это результат (совершенно отличный от полученного в Matlab):

введите описание изображения здесь

Очевидно, что результат scipy не соответствует минимальной поверхности.

Scipy.interpolate.Rbf + thin-plate работает так, как ожидалось, почему он отличается от результата Matlab?


person CodificandoBits    schedule 18.05.2013    source источник
comment
Какова именно связь между вашими трехмерными точками и желаемым результатом? У вас есть точки, которые приблизительно лежат на минимальной поверхности, и вы ищете алгебраическое описание этой поверхности? Или точки описывают какую-то границу, и вы ищете минимальную поверхность, определяемую этой границей? В какой форме должен быть ваш результат? Это может помочь увидеть весь код Matlab, чтобы можно было искать способы его перевода, даже не понимая интерпретации как минимальных поверхностей. Выглядит ли launchpad.net/cbcpdesys полезным?   -  person MvG    schedule 19.05.2013
comment
@MvG: подробнее см. В моем обновленном вопросе. (1) Точки лежат приблизительно на минимальной поверхности; (2) Точки описывают границу еще не полученной поверхности (3) В идеале поверхность, которую я хочу получить, представляет собой представление треугольной сетки.   -  person CodificandoBits    schedule 19.05.2013
comment
Попробуйте также спросить на scicomp.stackexchange.com.   -  person lhf    schedule 19.05.2013
comment
Если ваша цель - треугольная сетка, я предлагаю вам изучить дискретные минимальные поверхности. Вместо аппроксимации непрерывной минимальной поверхности с помощью треугольной сетки, дискретные минимальные поверхности происходят из дискретной версии теории минимальных поверхностей. В Википедии упоминается page.mi.fu-berlin.de/polthier/ article / diri / diri_jem.pdf в качестве справочного материала, что выглядит разумным. Google Scholar имеет много дополнительных ссылок . Возможно, для этого вам не нужно решать PDE, а вместо этого нужно только итеративно интегрировать вещи.   -  person MvG    schedule 19.05.2013
comment
Этот вопрос также был размещен на scicomp.stackexchange.com/q/7268 и аналогичном на math.stackexchange.com/q/396336/35416.   -  person MvG    schedule 20.05.2013


Ответы (3)


Вопрос гласит, что нам нужно решить нелинейное уравнение в частных производных. Однако Википедия утверждает, что «Их трудно изучать: почти нет общих методов, которые работают для всех таких уравнений, и обычно каждое отдельное уравнение нужно изучать как отдельную проблему». Однако вы не привели уравнение! И использует ли иногда Matlab генетические алгоритмы, чтобы достичь своих поверхностей? То есть, использует ли он эмпирическое правило, чтобы сделать наилучшее предположение, а затем пробует небольшие изменения в квадратах компонентов до тех пор, пока не удается найти меньшую поверхность. Реализация такого рода решения была бы трудоемкой, но не концептуально сложной (если вам нравятся подобные вещи). Также помните, что исчисление непрерывных функций - это просто частный случай исчисления всех линейных приближений функций (приращение устанавливается на ноль вместо некоторого конечного значения). Это стало мне ясно, когда я прочитал книги Дж. Л. Белла по гладкому инфинитезимальному анализу - просто используйте эту алгебру с конечными приращениями и оставьте результирующие множители в выводах, а не «пренебрегайте» ими.

person mistermarko    schedule 20.05.2013

Очевидно, что Matlab и SciPy по-разному понимают TPS. Реализация Matlab выглядит правильно. SciPy обрабатывает TPS так же, как другие RBF, поэтому вы могли бы правильно реализовать его на Python самостоятельно - этого было бы достаточно, чтобы сформировать матрицу соответствующей системы линейных уравнений и решить ее, чтобы получить коэффициенты TPS.

person nettvor    schedule 29.09.2013

Вы можете использовать FEniCS:

from fenics import (
    UnitSquareMesh,
    FunctionSpace,
    Expression,
    interpolate,
    assemble,
    sqrt,
    inner,
    grad,
    dx,
    TrialFunction,
    TestFunction,
    Function,
    solve,
    DirichletBC,
    DomainBoundary,
    MPI,
    XDMFFile,
)

# Create mesh and define function space
mesh = UnitSquareMesh(100, 100)
V = FunctionSpace(mesh, "Lagrange", 2)

# initial guess (its boundary values specify the Dirichlet boundary conditions)
# (larger coefficient in front of the sin term makes the problem "more nonlinear")
u0 = Expression("a*sin(2.5*pi*x[1])*x[0]", a=0.2, degree=5)
u = interpolate(u0, V)
print(
    "initial surface area: {}".format(assemble(sqrt(1 + inner(grad(u), grad(u))) * dx))
)

# Define the linearized weak formulation for the Newton iteration
du = TrialFunction(V)
v = TestFunction(V)
q = (1 + inner(grad(u), grad(u))) ** (-0.5)
a = (
    q * inner(grad(du), grad(v)) * dx
    - q ** 3 * inner(grad(u), grad(du)) * inner(grad(u), grad(v)) * dx
)
L = -q * inner(grad(u), grad(v)) * dx
du = Function(V)

# Newton iteration
tol = 1.0e-5
maxiter = 30
for iter in range(maxiter):
    # compute the Newton increment by solving the linearized problem;
    # note that the increment has *homogeneous* Dirichlet boundary conditions
    solve(a == L, du, DirichletBC(V, 0.0, DomainBoundary()))
    u.vector()[:] += du.vector()  # update the solution
    eps = sqrt(
        abs(assemble(inner(grad(du), grad(du)) * dx))
    )  # check increment size as convergence test
    area = assemble(sqrt(1 + inner(grad(u), grad(u))) * dx)
    print(
        f"iteration{iter + 1:3d}  H1 seminorm of delta: {eps:10.2e}  area: {area:13.5e}"
    )
    if eps < tol:
        break

if eps > tol:
    print("no convergence after {} Newton iterations".format(iter + 1))
else:
    print("convergence after {} Newton iterations".format(iter + 1))

with XDMFFile(MPI.comm_world, "out.xdmf") as xdmf_file:
    xdmf_file.write(u)

(Изменено с помощью http://www-users.math.umn.edu/~arnold/8445/programs/minimalsurf-newton.py.)

person Nico Schlömer    schedule 19.12.2019