Создание одномерной сетки для решения PDE
Я пытаюсь решить систему из двух УЧП, которые зависят от времени и расстояния (H [x, t] и P [x, t]). Я решаю проблему методом линий, но хочу сам сгенерировать сетку и ввести ее в NDsolve. Я хочу создать следующую сетку.

Мне нужна такая сетка, потому что значения одной из функций (P [x, t]) меняются со временем только очень близко к x = 0, тогда как H [x, t] изменяется во всей области 0 <x < xмакс. Ниже приведен пример кода, который я использую
(* Constants *)
f = 38.94; logL = -2;
Ls = 10^logL; a = 0.5;
C1 = 1*^-5; dH = 1*^-6;
Ea = 0.1;
tmax = 40; (* Time in seconds *)
xmax = 10 Sqrt[dH] Sqrt[tmax]; (* Maximum distance to simulate. cm *)
(* PDE system *)
eqsH = {D[H[x, t], t] - dH D[H[x, t], x, x] == NeumannValue[Ls Exp[a f Ea ] P[x, t] - Ls Exp[-a f Ea ] H[x, t],
x == 0], H[x, 0] == 1};
eqsP = {D[P[x, t], t] == NeumannValue[-Ls Exp[a f Ea ] P[x, t] + Ls Exp[-a f Ea ] H[x, t],
x == 0], P[x, 0] == 1};
(*Solution of the differential equations*)
prec = 7;
msf = 0.001;
sol = NDSolve[{eqsH, eqsP}, {H, P}, {x, 0, xmax}, {t, 0, tmax},
AccuracyGoal -> prec, PrecisionGoal -> prec,
Method -> {"MethodOfLines",
"SpatialDiscretization" -> {"FiniteElement"}}] // First //
Quiet;
Могу я получить некоторую помощь в том, как создать сетку и представить ее в NDSolve? заранее спасибо !
Ответы
Вот альтернативный подход с использованием градуированной сетки.
Определите некоторые вспомогательные функции для градуированной сетки
Вот несколько функций, которые я использовал для создания анизотропных сеток от 1d до 3D. Не все функции используются.
(*Import required FEM package*)
Needs["NDSolve`FEM`"];
(* Define Some Helper Functions For Structured Meshes*)
pointsToMesh[data_] :=
MeshRegion[Transpose[{data}],
Line@Table[{i, i + 1}, {i, Length[data] - 1}]];
unitMeshGrowth[n_, r_] :=
Table[(r^(j/(-1 + n)) - 1.)/(r - 1.), {j, 0, n - 1}]
meshGrowth[x0_, xf_, n_, r_] := (xf - x0) unitMeshGrowth[n, r] + x0
firstElmHeight[x0_, xf_, n_, r_] :=
Abs@First@Differences@meshGrowth[x0, xf, n, r]
lastElmHeight[x0_, xf_, n_, r_] :=
Abs@Last@Differences@meshGrowth[x0, xf, n, r]
findGrowthRate[x0_, xf_, n_, fElm_] :=
Quiet@Abs@
FindRoot[firstElmHeight[x0, xf, n, r] - fElm, {r, 1.0001, 100000},
Method -> "Brent"][[1, 2]]
meshGrowthByElm[x0_, xf_, n_, fElm_] :=
N@Sort@Chop@meshGrowth[x0, xf, n, findGrowthRate[x0, xf, n, fElm]]
meshGrowthByElm0[len_, n_, fElm_] := meshGrowthByElm[0, len, n, fElm]
flipSegment[l_] := (#1 - #2) & @@ {First[#], #} &@Reverse[l];
leftSegmentGrowth[len_, n_, fElm_] := meshGrowthByElm0[len, n, fElm]
rightSegmentGrowth[len_, n_, fElm_] := Module[{seg},
seg = leftSegmentGrowth[len, n, fElm];
flipSegment[seg]
]
reflectRight[pts_] := With[{rt = ReflectionTransform[{1}, {Last@pts}]},
Union[pts, Flatten[rt /@ Partition[pts, 1]]]]
reflectLeft[pts_] :=
With[{rt = ReflectionTransform[{-1}, {First@pts}]},
Union[pts, Flatten[rt /@ Partition[pts, 1]]]]
extendMesh[mesh_, newmesh_] := Union[mesh, Max@mesh + newmesh]
Создайте градуированный горизонтальный сегмент сетки
Далее будет создана область горизонтальной сетки из 100 элементов, где начальная ширина элемента составляет 1/10000 длины домена.
(*Create a graded horizontal mesh segment*)
(*Initial element width is 1/10000 the domain length*)
seg = leftSegmentGrowth[xmax, 100, xmax/10000];
Print["Horizontal segment"]
rh = pointsToMesh@seg
(*Convert mesh region to element mesh*)
(*Extract Coords from horizontal region*)
crd = MeshCoordinates[rh];
(*Create element mesh*)
mesh = ToElementMesh[crd];
Print["ListPlot of exponential growth of element size"]
ListPlot[Transpose@mesh["Coordinates"]]

Видно экспоненциальный рост размера элемента с увеличением номера элемента.
Преобразуйте область сетки в сетку элемента и решите PDE
Обычно я конвертирую в MeshRegion
элемент ElementMesh, чтобы при необходимости можно было применить маркеры элементов и точек.
(*Solve PDE on graded mesh*)
{Hfun, Pfun} =
NDSolveValue[{eqsH, eqsP}, {H, P}, x ∈ mesh, {t, 0, tmax},
Method -> {"MethodOfLines",
"SpatialDiscretization" -> {"FiniteElement"}}];
(*Animate Hfun solution*)
imgs = Plot[Hfun[x, #], x ∈ mesh,
PlotRange -> {0.9999999, 1.0018}] & /@ Subdivide[0, tmax, 120];
Print["Animation of Hfun solution"]
ListAnimate@imgs


Приложение: Примеры анизотропной сетки
Как я уже упоминал в комментарии ниже, маркированный список ниже показывает несколько примеров, в которых я использовал анизотропную четырехугольную сетку для захвата четких интерфейсов, которые в противном случае были бы очень дорогими в вычислительном отношении. Код функционален, но не оптимален, а некоторые функции со временем были изменены. Используйте на свой риск
- 2D-стационарный
- Mathematica против MATLAB: почему я получаю разные результаты для PDE с непостоянным граничным условием?
- Улучшение конвергенции сетки и решения NDSolve
- 2D-переходный процесс
- Управление размером динамического временного шага в NDSolveValue
- Как смоделировать диффузию через мембрану?
- Конечный элемент массового транспорта с использованием четырехугольной сетки
- NDSolve с системой уравнений с неизвестными функциями, определенными в разных областях
- 3D-сетка
- Создать градуированную сетку
- 3D-стационарный
- Как улучшить решение МКЭ с помощью NDSolve?
- 3D FEM векторный потенциал
Если у вас есть доступ к другим инструментам, таким как COMSOL, у которых есть функции пограничного слоя, вы можете импортировать сетки с помощью функции ресурсов FEMAddOns . Это не будет работать для трехмерных сеток, требующих дополнительных типов элементов, таких как призмы и пирамиды, которые в настоящее время не поддерживаются в FEM системы Mathematica .
Что насчет этого?
lst1 = Partition[
Join[Table[0.01*i, {i, 0, 5}], Table[0.1*i, {i, 0, 15}]], 1];
lst2 = Table[{i, i + 1}, {i, 1, Length[lst1] - 1}];
<< NDSolve`FEM`
mesh2 = ToElementMesh["Coordinates" -> lst1,
"MeshElements" -> {LineElement[lst2]}]
(* ElementMesh[{{0., 1.5}}, {LineElement["<" 21 ">"]}] *)
Давайте визуализируем это:
mesh2["Wireframe"["MeshElementIDStyle" -> Red]]

Красными цифрами обозначены элементы сетки. Место, где они перекрываются, на самом деле является тем местом, где сетка в 10 раз плотнее (см. Увеличенное изображение ниже):

Радоваться, веселиться!