Это мало. По таким разрывам, того и гляди, электричество пойдет. Возьмем-ка побольше.


Оказывается, числа с плавающей точкой и здесь готовят нам сюрприз. До 308 степени все идет нормально.


1e308
1e+308

Но вот...


1e309
inf

Что это за inf такой? Это, по-python-овски, бесконечность. По-английски, бесконечность - infinity.

Как говорили наши предки "больше сего числа несть уму разумети".

Очевидно, Python не прав. Ведь бывают числа, например 1e100000.

В математике, конечно, бывают и не такие. Но для большинства технических расчетов это, правда, все равно что бесконечность.

Как же быть?

Я не нашел библиотеки Python для точной работы со сверхогромными числами с плавающей точкой. Но при необходимости ее несложно написать.

А для наших целей inf - весьма привлекательный объект.

Его можно создать не только таким вот "округлением", но и c помощью функции по созданию чисел с плавающей точкой float()


float('inf')
inf
-float('inf')    #inf бывает отрицательным
-inf
5*float('inf')   #Бесполезно его умножать
inf
4+float('inf')   #Бесполезно к нему прибавлять
inf
1/float('inf')   #Деление на inf дает нуль.
0.0

Поскольку мы все время делим на сопротивление, последнеее свойство дял нас очень удобно - ток через участок с сопротивлением inf будет строго равен нулю, что и нужно для моделирования разрыва.


Добавим в программу строчку ρ[50] = float('inf') призванную разорвать наш замечательный проводник пополам.

И заменим в строке ρ=np.full(100,10) деятку на 10.0 - а то Python станет негодовать, что мы в массив целых чисел записываем число с плавающей точкой.






































%matplotlib tk
import matplotlib.pyplot as plt #Функции рисования графиков
import matplotlib.animation as animation #Функции анимации
import numpy as np #Для создания массивов в модели

ρ=np.full(100,10.0) #Массив сопротивлений между клетками
ρ[50] = float('inf') #Разрываем проводник посередине
ϕ=np.full(100,0.0) #Массив потенциалов в клетках
I=np.full(100,0.0) #Массив токов между клетками

def battery(): #Работа батареи
ϕ[0]=-4.5
ϕ[99]=4.5

def step(a):
Δϕ = ϕ[a]-ϕ[a+1] #Считаем разность потенциалов между клетками a и a+1
I[a]=Δϕ/ρ[a] #Найдем силу тока I(a)

def tick():
battery() #Батарея задает потенциалы на концах
for a in range(99): #Для каждой клетки
step(a) #Рассчитываем обмен потенциалами клетки a (со следующей)
for a in range(99): #Для каждой клетки
ϕ[a]-=I[a] #Потенциал утекает из клетки a
ϕ[a+1]+=I[a] #Потенциал притекает в клетку a+1

def animate(i):
for t in range(20): #20 раз
tick() #Проводим вычисления
line.set_ydata(ϕ) #Передаем линии новые данные
return line,

tick()

fig, ax = plt.subplots() #Создадим изображение (fig) и график (ax)
line, = ax.plot(ϕ) #А теперь саму линию, отображающую наш массив ϕ (первоначально).
ani = animation.FuncAnimation(fig, animate, interval=1, blit=True) #Создаем анимацию

О!

На мгновение мне покзалось, что ничего не изменилось. Но как только потенциалы встретились, они словно уперлись в невидимую стену и стали наполнять каждый свою половину - до упора.

Не забываем про инструмент "лупа", с помощью которого можно следить за нужными участками графика в сколь угодно увеличенном виде.



Вот как оно получилось:


ϕ



















array([-4.4999941 , -4.49994099, -4.49988203, -4.49982319, -4.49976452,
-
4.49970608, -4.49964792, -4.49959011, -4.49953269, -4.49947572,
-
4.49941926, -4.49936336, -4.49930808, -4.49925346, -4.49919957,
-
4.49914646, -4.49909416, -4.49904275, -4.49899226, -4.49894275,
-
4.49889425, -4.49884683, -4.49880053, -4.49875538, -4.49871144,
-
4.49866875, -4.49862734, -4.49858726, -4.49854855, -4.49851124,
-
4.49847537, -4.49844098, -4.4984081 , -4.49837675, -4.49834698,
-
4.4983188 , -4.49829225, -4.49826736, -4.49824414, -4.49822262,
-
4.49820281, -4.49818475, -4.49816844, -4.49815391, -4.49814116,
-
4.49813021, -4.49812107, -4.49811374, -4.49810824, -4.49810457,
-
4.49810274, 4.49903348, 4.4990345 , 4.49903652, 4.49903956,
4.4990436 , 4.49904865, 4.4990547 , 4.49906173, 4.49906975,
4.49907875, 4.49908871, 4.49909963, 4.4991115 , 4.49912429,
4.499138 , 4.49915262, 4.49916813, 4.49918451, 4.49920174,
4.49921981, 4.4992387 , 4.49925839, 4.49927886, 4.49930008,
4.49932204, 4.4993447 , 4.49936806, 4.49939208, 4.49941673,
4.499442 , 4.49946785, 4.49949426, 4.4995212 , 4.49954865,
4.49957656, 4.49960492, 4.4996337 , 4.49966286, 4.49969237,
4.49972221, 4.49975234, 4.49978272, 4.49981334, 4.49984415,
4.49987512, 4.49990623, 4.49993743, 4.4999687 , 4.49999687])

Отключим батарею, переопределив ее функцию на ничегонеделание. Совсем без команд функции или циклу нельзя, а вот pass (по англйиски - "пропустить", "пройти мимо") - самое то.



def battery():
pass #команда ничего-не-делания

И - вперед!




fig, ax = plt.subplots()   #Создадим изображение (fig) и график (ax)
line, = ax.plot(ϕ) #А теперь саму линию, отображающую наш массив ϕ (первоначально).
ani = animation.FuncAnimation(fig, animate, interval=1, blit=True) #Создаем анимацию


Как и следовало ожидать, ничего не происходит. А между тем, мы наблюдаем физическое явление - заряженные и изолированные от всего проводники сохраняют свой потенциал неизменным.

Теперь соединим половинки между собой:


ρ[50] = 10.0 

Хочется скорее запустить анимацию - вдруг что-то важное уже происходит без нас! Но это же модель, она не двигается с места без команды.

Дадим же команду на пуск анимации (пора уже, наверное, вынести ее в функцию):




fig, ax = plt.subplots()   #Создадим изображение (fig) и график (ax)
line, = ax.plot(ϕ) #А теперь саму линию, отображающую наш массив ϕ (первоначально).
ani = animation.FuncAnimation(fig, animate, interval=1, blit=True) #Создаем анимацию




По отвесным прямоугольным горам потенциала от середины несется лавина разрушения. Вот она доходит до краев и горы становятся угасающими пологими холмиками. Через некоторое время - перед нами уже равнина.

Вот так красиво исчезают противоположные потенциалы в отсутствие батарейки.


Выбери следующий вопрос: