Фиксированные граничные условия потока в FiPy

У меня есть дополнительный вопрос к этой теме Связанные нелинейные уравнения в FyPi. Мне удалось настроить систему и получить разумные результаты при использовании граничных условий Неймана для всех переменных (т.е. поддерживая постоянные концентрации электронов и дырок и потенциалов на границах).

Система уравнений

Теперь я хотел бы сравнить это с ситуацией, когда потоки электронов (n) и дырок (p) связаны соотношениями:

Граничные условия

где n 0 (0), p 0 (0) - равновесные концентрации на левой границе, аналогично уравнения были бы для правой части границы. s - скорость рекомбинации.

Мне известно об этом описании в документации (https://www.ctcms.nist.gov/fipy/documentation/USAGE.html#applying-fixed-flux-boundary-conditions), но не знаю, как его применить.

Поскольку граничные условия учитывают концентрации на краях, следует ли определять переменные n, p, phi как FaceVariables? Не могли бы вы помочь мне с определением этих граничных условий?


person josefT    schedule 10.07.2020    source источник


Ответы (1)


Исходный вопрос

Рассмотрим просто уравнение для электронов. В FiPy это будет выглядеть примерно так:

eqn = TransientTerm(var=var_n) == G - R - DiffusionTerm(coeff_phi, var=phi) + DiffusionTerm(coeff_n, var=var_n) + boundary_condition

Чтобы решить эту проблему с правильным граничным условием, нам нужно обнулить поток в и из области в условиях диффузии в левой части и добавить поток для граничного условия. coeff_phi и coeff_n - коэффициенты диффузии, которые зависят от различных параметров. coeff_phi также зависит от n_var. Чтобы обнулить использование флюса,

coeff_phi.constrain(0., mesh.facesLeft)
coeff_n.constrain(0., mesh.facesLeft)

Для построения граничного условия используйте:

boundary_condition = (mesh.facesLeft * s * (n_var.faceValue - n0) / charge).divergence

Я предполагаю, что n0 изменяется со временем, поэтому это должен быть объект Variable, который обновляется с шагом во времени в зависимости от его отношения ко времени. Я предполагаю, что s - это какое-то постоянное значение.


Определение коэффициентов равными 0 (вопрос из комментария)

Чтобы уточнить, есть два способа поддерживать нулевой коэффициент на границе.

Использование ограничений

Учитывая коэффициент, определенный как операция с FaceVariables, следующее работает должным образом (левая сторона остается равной нулю).

from fipy import Grid1D, FaceVariable

mesh = Grid1D(nx=10, dx=0.1)
var0 = FaceVariable(mesh=mesh, value=1 - mesh.x.faceValue)
var1 = var0 * var0
print('before constraint:', var1)
var1.constrain(0, where=mesh.facesLeft)
print('after constraint:', var1)
var0[0] = 10.0
print('after var0 reset:', var1)

Умножение на ~mesh.facesLeft

Это альтернативный подход к использованию ограничений, который может быть легче контролировать и понимать. Используйте это, если вы не доверяете ограничениям, чтобы поступать правильно. ~mesh.facesLeft - это логический массив, поэтому его можно использовать как ограничение.

from fipy import Grid1D, FaceVariable

mesh = Grid1D(nx=10, dx=0.1)
var0 = FaceVariable(mesh=mesh, value=1 - mesh.x.faceValue)
var1 = var0 * var0 * ~mesh.facesLeft
print('using ~mesh.facesLeft:', var1)
var0[0] = 10.0
print('after var0 reset:', var1)
person wd15    schedule 14.07.2020
comment
Большое спасибо за Ваш ответ. Я понимаю термин boundary_condition, но у меня проблемы с ограничением коэффициентов до нуля. Кроме того, я определил уравнение немного иначе, поэтому оно выглядит примерно так: eq1 = TransientTerm(var=var_n) == G - R - ConvectionTerm(coeff=mu_n*var_phi.faceGrad, var=var_n) + DiffusionTerm(coeff=D_n, var=self.n) И mu_n, и D_n являются константами. Поэтому я попытался определить коэффициенты для терминов ковекции и диффузии как Variable(), но получал различные ошибки (значение, индекс или VectorCoeffError). - person josefT; 15.08.2020
comment
Итак, как мне определить эти коэффициенты, пожалуйста? - person josefT; 15.08.2020
comment
Я изменил ответ, чтобы, надеюсь, ответить на ваш вопрос о комментариях. Of D_n - это просто число с плавающей запятой, тогда вы можете создать FaceVariable с помощью D_n * ~mesh.facesLeft и, вероятно, это то, что вы хотите. - person wd15; 17.08.2020