===== Функция на сетке ===== Важная особенность ''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)