===== Функция на сетке =====
Важная особенность ''np.array'' — возможность обходиться при вычислении значения функции **без циклов**.
import numpy as np
def f(x,y):
return x**2+2*x+6*y
s = np.linspace(1,7,3)
p = np.linspace(5,9,3)
v = f (s,p) # Функция f была применена поэлементно
# v == array([ 33., 66., 117.])
S, P = np.meshgrid(s,p,indexing='ij')
v = f (S,P) # Функция f была применена для каждой пары из s и p
# array([[ 33., 45., 57.],
# [ 54., 66., 78.],
# [ 93., 105., 117.]])
В случае простой подстановки ''f (s,p)'' будет массивы будут подставлены поэлементно. В случае подстановки с использованием ''meshgrid'' из массивов будет построена сетка, в узлах которой будут пары элементов и функция будет рассчитана для каждого элемента сетки.
===== Дифференциальные операторы на сетке =====
Для расчетов производных на сетке будем использовать модуль ''findiff''pip ([[https://findiff.readthedocs.io|документация]]).
import numpy as np
from findiff import FinDiff
x = np.linspace(0, 10, 100)
dx = x[1] - x[0]
f = np.sin(x)
d_dx = FinDiff(0, dx, 1)
df_dx = d_dx(f)
Объект ''FinDiff'' реализует дифференциальный оператор, аргументы: ''0'' — по первой оси, ''dx'' — размер шага, ''1'' — первая производная.
''df_dx'' — массив ''np.array'' со значениями производной ''f'' в узлах сетки. Модуль ''findiff'' не изменяет размер массива т.к. на краях применяется схема дифференциирование вперед или назад соответственно, а по остальному объему массива используется центральная схема.
==== Дифференциальные операторы модуля findiff ====
^ Название ^ Значение ^ Запись ^ Вход ^ Выход ^
| FinDiff | дифференциал | d/dx | скалярное поле | скалярное поле |
| Gradient | градиент | ∇f | скалярное поле | векторное поле |
| Laplacian | оператор Лапласа | ∇2 f | скалярное поле | векторное поле |
| Divergence | дивергенция | ∇· f | векторное поле | скалярное поле |
| Curl | ротор | ∇×f | векторное поле | векторное поле |
==== В 2D задаче ====
import numpy as np
from findiff import Gradient, Divergence, Laplacian
import matplotlib.pyplot as plt
#%%
borders = [-2*np.pi, 2*np.pi, -2*np.pi, 2*np.pi]
x = np.linspace(-2*np.pi, 2*np.pi, 30)
dx = x[1]-x[0]
y = np.linspace(-2*np.pi, 2*np.pi, 30)
dy = y[1]-y[0]
X, Y = np.meshgrid(x, y, indexing='ij')
f = Y*np.sin(X) + np.cos(Y)
#%%
plt.imshow(f.T, origin='lower', extent=borders)
contours = plt.contour(X, Y, f, origin='lower', colors = 'r')
plt.clabel(contours, colors = 'r')
plt.show()
#%%
grad = Gradient(h=[dx, dy])
grad_f = grad(f)
plt.imshow(f.T , origin='lower', extent=borders)
plt.colorbar()
plt.quiver(X,Y,grad_f[0],grad_f[1])
plt.show()
#%%
u = np.array((X**2-Y**2, Y**2-X))
div = Divergence(h=[dx, dy])
div_u = div(u)
plt.imshow(div_u.T,origin='lower', extent=borders)
plt.colorbar()
plt.quiver(X,Y,u[0],u[1])
plt.show()
== Скалярная функция f и ее изолинии ==
{{:calc:f_foo.png?400|Скалярная функция f и ее изолинии}}
== Скалярная функция f и ее градиент ==
{{:calc:f_grad_foo.png?400|Скалярная функция f и ее градиент}}
== Векторная функция u и ее дивергенция ==
{{:calc:f_div_foo.png?400|Векторная функция u и ее дивергенция}}
==== В 3D задаче ====
import numpy as np
from findiff import Gradient, Divergence, Laplacian, Curl
x = np.linspace(0, 10, 100)
dx = x[1]-x[0]
y = np.linspace(0, 10, 100)
dy = y[1]-y[0]
z = np.linspace(0, 10, 100)
dz = z[1]-z[0]
X, Y, Z = np.meshgrid(x, y, z, indexing='ij')
f = np.sin(X) * np.cos(Y) * np.sin(Z)
grad = Gradient(h=[dx, dy, dz])
grad_f = grad(f)
laplace = Laplacian(h=[dx, dy, dz])
laplace_f = laplace(f)
g = np.array([f, 2*f, 3*f])
div = Divergence(h=[dx, dy, dz])
div_g = div(g)
curl = Curl(h=[dx, dy, dz])
curl_g = curl(g)